Cross-site scripting is another common security issue to consider when developing web applications. It happens when you allow the users of your site to enter HTML or JavaScript directly. In the website below we’re not escaping the input that’s entered in the comments textbox, which leaves our site vulnerable.
f we enter JavaScript into the comment box, surrounded by <script> tags, that script will be executed when the page reloads and every time it it viewed afterwards. For example if we entered <script>alert(’hello’)</script> into the comments box and clicked the button then every subsquent time the page is viewed the user would see an alert box.
<h2>Comments</h2>
<p>I'll start on this now - Paul</p>
<p><script>alert('hello!');</script></p>
<hr/>
Causing an alert box to be shown on a page is annoying, but cross-site
scripting can be used for much more malicious purposes. For example it
could be used to read the cookies for the site’s other users. We’ll just
alert the cookie, but it could just as easily be sent to a remote
server where the session id information in the cookie could be used to
hijack another user’s session
Stopping The Attacks
To stop these attacks you need to escape any user input before you display it on the screen. We’re currently taking the comment’s content directly from the database and outputting it into the HTML stream. Rails provides a method simply called h to escape the content before it is output.
h
command escapes the angle brackets so that the comments entered by the user are displayed safely.sanitize
method which allows
certain tags to be included via a white list. To be on the safe side and
escape any HTML that may be entered by a user it is safer to stick to h
.
An Alternative Approach
Instead of escaping the user’s input when sending it out to the browser we could escape it when we store it in the database. Theh
method isn’t available in a controller so instead we’ll use CGI::escapeHTML()
.
- def create
- @task = Task.find(params[:task_id])
- @comment = @task.comments.new(params[:comment])
- @comment.content = CGI::escapeHTML(params[:comment][:content])
- @comment.save
- redirect_to task_path(@task)
- end
Escaping the comment’s HTML before it is stored in the database.
Storing escaped HTML in the database is fine as long as you only ever
want to display that data in a browser. If you think you might need it
in its unescaped form as well then it’s better to escape the output with
h
.
No comments:
Post a Comment