Security: Session Attacks

Lecture Notes for CS 142
Fall 2010
John Ousterhout

  • Readings for this topic: none.

Session Token Hijacking

  • If an attacker can guess or steal the token associated with your session, he/she can impersonate you.
  • Example: predictable session token
    • Server picks session token by incrementing a counter for each new session.
    • Attacker opens connection to server, gets session token.
    • Subtract 1 from session token: can hijack the last session opened to the server.
  • Solution: session tokens must be unpredictable.
    • Don't build your own mechanism! Use something provided by your framework.
    • Example: Rails token = MD5(current time, random nonce)
  • Even if session tokens chosen carefully, network attackers can read cookies from unencrypted connections. Sessions not using HTTPS inherently vulnerable to network attacks.
  • HTTP/HTTPS upgrades:
    • Suppose session starts out with HTTP, converts to HTTPS after login.
    • Network attacker could have read session token during HTTP portion of session.
    • Once logging is complete, attacker can use the token to hijack the logged in session.
    • Solution: change the session token after any upgrade in privileges.

Cross-Site Request Forgery (CSRF)

  • Attackers can potentially hijack sessions without even knowing session tokens:
    • Browser always includes cookies in requests to a particular server.
    • Scenario:
      • Visit your bank's site, log in.
      • Then visit the attacker's site (e.g. sponsored ad from an untrusted organization).
      • Attacker's page includes form with same fields as the bank's "Transfer Funds" form.
      • Form fields are pre-filled to transfer money from your account to attacker's account.
      • Attacker's page includes Javascript that submits form to your bank.
      • When form gets submitted, browser includes your cookies for the bank site, including the session token.
      • Bank transfers money to attacker's account.
      • The form can be in an iframe that is invisible, so you never know the attack occurred.
    • This is called Cross-Site Request Forgery (CSRF).
  • CSRF solution:
    • Every form must contain an additional authentication token as a hidden field.
    • Token must be unpredictable (attacker can't guess it).
    • Server provides valid token in forms in its pages.
    • Server checks token when form posted, rejects forms without proper token.
    • Example token: session identifier encrypted with server secret key.
    • Rails automatically generates such tokens: see the authenticity_token input field in every form.

Data Tampering

  • Server can't pass information to the browser and count on the browser to return it.
  • Example:
    • Server is expected to be stateless.
    • But, sometimes information is generated at the time a form is created, needed later on when the form is submitted.
    • One possible approach: include the information as hidden form fields; they will be returned when the form is posted.
    • Unfortunately, an attacker can modify these fields before the form is submitted.
    • Similar issues exist for cookies, AJAX requests, URL query values.
  • Bottom line: server data coming from the browser is only as trustworthy as the user.
  • Solution #1: use Message Authentication Codes (MACs) to validate the sensitive data:
    • MAC function takes arbitrary-length text, secret key, produces a MAC that provides a unique signature for the text.
    • Without knowing the key, cannot generate a valid MAC.
    • Server includes MAC with data sent to the browser.
    • Browser must return both MAC and data.
    • Server can check the MAC using its secret key to detect tampering.
    • Problem: not always clear which data is sensitive, easy to forget MACs (MACs add complexity).
  • Solution #2: keep the state on the server, store it in the session. Unfortunately, this is hard to manage:
    • Session could include state from several different pages; must keep all of this information separate.
    • When can state be deleted from session?
    • User can display a form, go onto other pages, come back to form, and submit: still need state information.
    • Can't keep forever: results into much session state on server.