Securing a

(Ruby on Rails)

WeBApplication



Why Be Secure?


  • Your users trust you. Don't let them  down.
  • Bad reputation.
  • Money loss.
  • Lawsuits.
  • Because you are a professional.


"It will definitely drive. It might explode, though... - or lose your luggage."

Dramatis Personae

Peter the Programmer
Mike the Manager

Dramatis Personae (2)

Simon the Security Specialist
H4nk d4 H4XX0r

Dramatis Personae (3)

Erin the End-User
Alex the Application Administrator

Show of Hands


  • Who's running a high-profile website?
    You're a target
  • Who's processing personal data?
    You're a target
  • Who has personal profiles on their site?
    You're a target
  • Who's processing textual input in some way?
    You're likely to be or become vulnerable
  • Who's accepting file uploads in some way?
    You're likely to be or become vulnerable

YES, You're a target too






About this presentation


  • Google hints
  • Principles
  • Some contrived examples / not all exact
  • For some of you, none of this will be new. Sorry 'bout that.
  • Templates, as per Fowler:

What is it?
Why is it a problem?

When may you be vulnerable?
How do we prevent it?

    What are we talking about?


    • Some XSS
    • Some CSRF
    • Some SQL Injection
    • Some file uploading
    • Some assorted items I'll loose sleep over if I don't mention them and one of you trips over it.

    XSS: What is it?

    Injecting JavaScript to be executed in someone else's browser

    1. Mike wants the website to take user-generated content (for example, profile description or status updates).
    2. H4nk says: "<script>alert('You just got owned'); </script>"
    3. "I just got owned!"

    XSS - SO *WHY* IS IT A PROBLEM?


    • If you have access to JavaScript, you can control the whole site on behalf of the executing user. All of it. Think 'administrators' to get an idea of how bad this is.

    XSS - WhEN is it a problem?

    Search boxes, content editing, etc:

    • Anytime a user can do something meaningful in a webapp. That is, more than just reading stuff.
    • Anytime you repeat any user input - including search queries - in the HTML output.

    XSS - FIXING THINgs



    content.gs­ub(/<\/?scri­pt>/,'')
    "Let's not do that!"

    Principle number 1

    Blacklisting will never help you.


    <scr<script></script>ipt>alert('boo');</script>
    will turn into:
    <script>alert('boo');</script>

    Roll your own WHITELISTER


    Nokogiri.parse....




    Principle #2:
    Never "roll your own" unless you have to.

    Libraries

    • ActionView / ActionPack has a 'sanitize' method.
    • Sanitize by Ryan Grove provides more control
      (https://github.com/rgrove/sanitize)
      * based on Nokogiri and Whitelisting
      * (MIT License)

    CSRF: WHAT IS IT?

    Cross Site Request Forgery

    1. Mike wants to be able to delete users. Peter makes an API endpoint, like this:
      [GET] https://site.com/delete_user/5
    2. H4nk lures Alex the Application Administrator to some website where a fake image is located:
      <img src="https://site.com/delete_user/5">
    3. "Where did my profile go?"

    CSRF


    Example of a so-called Confused Deputy Attack: makes some client accidentally abuse privileged status.

    CSRF - Why is this a problem?


    • Annoying:
    <img src="/logout">
    • Dangerous:
    <img src="/delete_profile">

    CSRF - When may it occur?


    If you have any non-idempotent actions in any controller

    ... which is more or less the same as ...

    If any of your users can change the state of your application in any way.

    CSRF - How do we prevent it?


    Only idempotent controller actions are allowed to be accessible via HTTP GET (adhering to REST might help).



    "But you're not out of the woods yet, since cross-domain POST is still possible."

    CSRF - HOW DO WE PREVENT IT? (2)


    Pre-sign each outgoing form with a token and remember it at the server side. Then, on each incoming form, verify if the token was handed out by you.


    It's a little like a dry-stamp used to verify the authenticity of the form itself, instead of the contents of the form.


    Rails will do this for you, if you do not disable this behavior.

    SQL Injection: what is it?

    • User profile at /user/:id
    • Code contains something like:                                                   
      User.find_by_sql("SELECT * FROM users WHERE id=" + params[id])
    • H4nk visits:
      "/user/1; DROP TABLE users;"
    • Peter, Mike, Alex, Erin and Simon all freak out.

    SQL INJECTION - Why is this A problem?


    ....

    I'm not even explaining that.


    SQL INJECTION - When MIGHT this BE A problem?


    If you have any dynamic queries at all.

    SQL Injection - Prevention


    This one's easy:
    Know your framework.

    ActiveRecord, for example, has all kinds of SQL injection preventions in place:
    User.find_by_sql("SELECT * FROM users WHERE id=" + params[:id]) # unsafe!
    User.find_by_sql("SELECT * FROM users WHERE id = ?", params[:id]) # safe! 

    See also: rails-sqli.org

    File uploads / DOWNLOADS

    • HTML with Content-Disposition: inline  may contain script executed directly in the browser. Back to XSS.

    • Any unprocessed content might be dangerous: the file extension may lie and <script src='owned.gif'> will just work! Welcome back to XSS.

    • Prevention: separate subdomains for file uploads to trigger Same Origin Policy.

    • Be on the lookout for path traversal, which is breaking out of the folder structure by using '../'-style relative paths.

    Assorted Items: Authentication


    • Hash and Salt your passwords, if you need to store them at all.

    • MD5 is not cool anymore (read up on Rainbow Tables) - prefer bCrypt.

    • Do not make up your own encryption scheme (Schneier's Law).

    • Use HTTPS everywhere, but especially where credentials are passed over the line.

    Assorted items: COOKIES


    • Make them HTTPOnly if your JS doesn't need them.
    • Never put sensitive data in there.
    • Never put important data in there (see replay attack).
    • In fact, never put data in there except for keys to server-side storage.


    Assorted Items: Environment


    Story time: refactoring LDAP authentication!

    Client: "Hi, I'm Bob"
    Server: "Can you prove that?"
    Client: "No, not really"
    Server: "Oh well. You seem like a standup guy. Here ya go.”



    Assorted items: Secret Token


    Show of hands: 
    Who committed everything after the initial 
    rails new [appname]
    ?

    Your session-signing token is exposed, which allows H4nk to generate valid sessions.

    See here for more.

    Assorted items: caching


    Is your cache key and strategy set up in such a way that non-privileged users will just not receive the secret data?


    Assorted items: HTTPS


    HTTPS. No discussion. Get it fixed.

    (Preferably configuring the server not to use outdated encryptions like DES-56 - which can be broken in 1 day).

    Assorted Items: Validations


    This is probably wrong!
    validates_format_of :name, with: /^[a-z ]+$/i
    It will match, for example, this little gem:
    Joe User
    <script>alert("Boo hoo");</script>
    
    Did you mean...
    validates_format_of :name, with: /\A[a-z ]+\z/i

    ASSORTED ITEMS: (D)DOS


    You cannot prevent it
    You can, however, make it so easy that the first D is no longer even needed:

    • Synchronous image resizing
    • Synchronous video transcoding
    • Using to_sym on a user-provided parameter

    Resources




    Questions?

    rorsecurity

    By reneb

    rorsecurity

    • 1,261