Friday 10 February 2012

Cross-site Scripting


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.





If we look at the source of the page we can see the JavaScript embedded in it.





<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.
  • <% @task.comments.each do |comment| %>  
  •   <p><%= h(comment.content) %></p>  
  • <% end %>
  • Now, when we reload the page we can see that the script is no longer executed. The h command escapes the angle brackets so that the comments entered by the user are displayed safely.
  • Rails also provides a 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. The h method isn’t available in a controller so instead we’ll use CGI::escapeHTML().
    1. def create  
    2.   @task = Task.find(params[:task_id])  
    3.   @comment = @task.comments.new(params[:comment])  
    4.   @comment.content = CGI::escapeHTML(params[:comment][:content])  
    5.   @comment.save  
    6.   redirect_to task_path(@task)  
    7. 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.
    1. http://en.wikipedia.org/wiki/Session_hijacking

    No comments:

    Post a Comment