Web Security

Using OWASP Guidelines 

*Most of the content of the presentation is taken from the  presentation by Brian Huff

What is OWASP?

OWASP stands for Open Web Application Security Project. It is a not for profit organization dedicated to improving web security.


What we will learn?

Top 10 Web Security mistakes developer make and what kind of measures we can take to protect against it.


Top 10 Security Mistakes

  1. Injection
  2. Cross Side Scripting 
  3. Broken Authentication and Session Management
  4. Insecure Direct Object Reference
  5. Cross Site Request Forgery (CSRF)
  6. Security Misconfiguration
  7. Insecure Cryptographic Storage
  8. Failure to Restrict URL Access
  9. Insufficient Transport Layer Protection
  10. Unvalidated Redirects and Forwards

1. Injection

Injection flaws, such as SQL, OS, and LDAP injection, occur when untrusted data is sent to an interpreter as part of a command or query. The attacker’s hostile data can trick the interpreter into executing unintended commands or accessing unauthorized data.

Hacker "inject" their code to run instead of yours.

They can happen to any system which accepts user inputted data and pass it to other system.

Example 

attackableQuery= "Select * from products where name=" + params[:id] + "'";
# Code expects a parameter in the url like  http://www.example.com/products?id=123
# Hacker could instead supply this http://example.com/products?id="; DROP+TABLE+'products';


Countermeasures

  1. Always assume data you are getting could be "evil" and it can never be trusted.
  • make sure to include in your tests and user stories scenarios where data is evil and how will you handle it
  • Ideally, only ask users to select from only "safe" options.
  • If user-input is required use parameterized queries
    •  e.g. in hibernate you can use parameter binding setString(..) etc to sanitize the data
    • clean up quotes, parenthesis and SQL comments
  • Be careful at the junction of the two systems, these are highly vulnerable.

  • 2. Cross Site Scripting

    XSS flaws occur whenever an application takes untrusted data and sends it to a web browser without proper validation and escaping.  XSS allows attackers to execute scripts in the victim’s browser which can hijack user sessions, deface web sites, or redirect the user to malicious sites.

         Hackers can create URLs to inject their own HTML onto the page.

    html_safe can easily open us to this attack if we trust user inputted data.




    Example

    class SearchController
      
      def show
        @title = params[:title]
        @results = call_to_backend
      end
    end
    
    
    #index/show.html.erb
    
    <div id="title">
      (@results.title || @title).html_safe
    </div>
    
    

    # Allowing GET requests to change the state of the resource
    
    <img src="http://www.webapp.com/project/1/destroy">
    
    

    Countermeasures

    • Never ever trust the user-submitted data
      • URLs,  comments etc.
    • It's extremely important to know the data we are marking it to be html_safe is 'actually' safe. 
    • Setting the httponly flag on cookie to not allow to fetch certain cookies from javascript
      • eg.  cookies["user_session"] = { :value => "secrethash", :httponly => true }
    • Our backend currently does the escaping, so we can assume anything from backend is safe. Otherwise we will have double escaping issue.
    • We shouldn't allow GET request to do any state change like update, destroy etc.

    3. Broken Authentication & Session Management

    Application functions related to authentication and session management are often not implemented correctly, allowing attackers to compromise passwords, keys, session tokens, or exploit other implementation flaws to assume other users’ identities.

    In case of broken session management, session-id can be sniffed using wire-shark or other packet sniffing software.

    session-ids exposed in the url can be used when the url is shared


    Example

    Timeouts aren't set properly and user logs in terminal at library and then closes the browser instead of logging out. Then next user goes to the terminal and the user is still logged in. 
    

    #Session ID is exposed as URL
    
    http://example.com/sale/saleitems;jsessionid=2P0OC2JDPXM0OQSNDLPSKHCJUN2JV
    ?dest=Hawaii
    
    




    Countermeasures

    • Use SSL wherever possible, this will make it extremely difficult to sniff session-ids.
    • Encrypt your session-ids and include user-ip's, username and timestamp in your session-id. 
      • Forces the user to include spoof IP addresses
    • We need to figure out what kind of damage can hacker makes when the session-id is stolen.
      • We need to do some kind of audit assuming the session-id is stolen especially if its stolen for admin. 
      • Should we ask user's to re-login to access extremely sensitive data?

    4. Insecure Direct Object Reference

    A direct object reference occurs when a developer exposes a reference to an internal implementation object, such as a file, directory, or database key. Without an access control check or other protection, attackers can manipulate these references to access unauthorized data.

    If you can access other protected resource by guessing or altering the url then you can be open yourself to this attack

    Checking if user is only authenticated is not enough



    Example

    # your collections url
    
    http://opl.bibliocommons.com/projects/1
    
    
    class ProjectsController
      before_filter :authenticate
      
      def show
        @project = @project_service.get(params[:id])
      end
    
      def authenticate
        #verify if the user is logged in
      end
    end
    
    # The mistake is logged in user can easily change the url and get the project # 2 as long as user is logged in.
    
    

    Countermeasures

    • Add resource level access control 
      • eg. Giving this particular project and this user, does the user have read rights, write rights etc.
    • Try to keep all the access level code in one place, so its simpler and easier to maintain. 
    • Currently our backend system does lot of access level checking but its baked into each actions on the backend. It would be great to extract out into separate module which can be shared on both backend and front-end. 

    5. Cross Site Request Forgery (CSRF)


    A CSRF attack forces a logged-on victim’s browser to send a forged HTTP request, including the victim’s session cookie and any other automatically included authentication information, to a vulnerable web application. This allows the attacker to force the victim’s browser to generate requests the vulnerable application thinks are legitimate requests from the victim.

    Using a session from one website and executing it in another website.


    Example

    The application allows a user to submit a state changing request that does not include anything secret. For example:
    http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243


    So, the attacker constructs a request that will transfer money from the victim’s account to the attacker’s account, and then embeds this attack in an image request or iframe stored on various sites under the attacker’s control:

    <img src="http://example.com/app/transferFunds?amount=1500&destinationAccount=attackersAcct#" width="0" height="0" />

    If the victim visits any of the attacker’s sites while already authenticated to example.com, these forged requests will automatically include the user’s session info, authorizing the attacker’s request.

    Countermeasures

    • All state change should require a unique token in the request.

      • Rails does that for us when we switch on protect_from_forgery. It automatically adds to all the forms this token called "authenticity_token" and for every request where this token doesn't match it resets the session
      • Our app need to actually logout on the failure, there is a ticket in the backlog which will fix this problem fro us.
    • If the token is part of the URL then we have to make sure our tokens are not re-usable
    • General Solution
      • All state change requires HTTP POST not a GET
      • One time token in a hidden field on the web form (done by Rails for us)

    References

    • http://www.slideshare.net/bexmex/top-10-web-security-vulnerabilities-owasp-top-10#btnNext  (Lot of the content is taken from this presentation)
    • https://www.owasp.org/index.php/Top_10_2010-Main
    • https://www.owasp.org/index.php/Top_10_2013-Top_10
    • https://www.owasp.org/index.php/Ruby_on_Rails_Cheatsheet