Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Putting Web Security Issues to REST

Duo Security
January 16, 2012

Putting Web Security Issues to REST

Abstract: A common security mantra is "don't roll your own" - but when developing modern web APIs, this may seem easier said than done. Unlike older, over-specified API protocols, the general concepts which underpin REST APIs do not offer much guidance on security best-practices. Worse still, some techniques that have gained widespread use have been shown to be fundamentally flawed. This session will cover some common classes of mistakes in developing and using secure web APIs, and show how reinventing the wheel can sometimes be dangerous. Along the way, we'll cover problems with authentication and authorization, information leakage, and (im)proper uses of transport-layer security, among others.

Bio: Adam Goodman is a co-founder and Principal Security Engineer at Duo Security, where he and his cohorts work to radically improve the ease-of-use in strong authentication systems. He was previously a founding engineer at Zattoo, Europe's largest live-streaming Internet TV operator, where he led the development of the secure P2P distribution and digital rights management protocols that carried the first live broadcasts of Europe's second-largest pay TV operator over the Internet. Adam also enjoys puns way too much for his own good...

Duo Security

January 16, 2012
Tweet

More Decks by Duo Security

Other Decks in Technology

Transcript

  1. SSL CERTIFICATE VALIDATION ˒  Is the name on the certificate

    correct? ˒  HTTPS: does it match the server`s hostname ˒  Was the certificate issued by a trusted authority? ˒  Is the certificate`s signature correct? ˒  Is the certificate unexpired?
  2. PYTHON FAIL! In Python versions before 3.2, there is no

    support in the Standard Library (urllib / h plib) for checking SSL certificates while performing HTTPS requests
  3. PYTHON FAIL! ˒  python-cloudfiles (Rackspace CloudFiles client SDK) ˒  recurly-client-python

    ˒  boto* (widely-used python AWS client library) ˒  many others... * boto recently implemented support for checking CA certificates, but it remains disabled by default.
  4. OTHER PYTHON HTTP LIBRARIES PyCURL YES NO h plib2 YES

    YES urllib3 YES NO Twisted NO* NO * Twisted can check CA signatures, but can’t verify that the certificate matches the hostname
  5. OTHER ENVIRONMENTS Ruby (NET:HTTP) YES NO* Java (java.net.URL) YES YES

    .NET (System.net.WebClient) YES YES Cocoa (NSURLConnection) YES YES * Ruby’s NET:HTTP library will log a warning to the console by default
  6. SSL CERTIFICATE VALIDATION ˒  Is the name on the certificate

    correct? ˒  HTTPS: does it match the server`s hostname ˒  Was the certificate issued by a trusted authority? ˒  Is the certificate`s signature correct? ˒  Is the certificate unexpired? ˒  Has the certificate been revoked?
  7. REVOCATION... ˒  Certificate Revocation Lists (CRLs) ˒  Certificate Authority publishes

    a (signed) list of certificate IDs that should no longer be considered valid ˒  Online Certificate Status Protocol (OCSP) ˒  Given a certificate ID, returns a (signed) response indicating whether that certificate is still valid
  8. REVOCATION... ˒  ... doesn`t really work... ˒  Applications and libraries

    frequently don`t check CRLs or OCSP ˒  Even those that do will rarely complain if they can`t reach the server hosting the CRL or OCSP service
  9. TRUSTING CERTIFICATE AUTHORITIES ˒  Over 150 Root Authorities are trusted

    by most OS`s and browsers ˒  Even scarier - intermediate authorities beneath them also can issue certificates for anyone ˒  Cross-signing: sometimes, lesser-known root authorities act as intermediate authorities, signed off by other - more trusted - root authorities (e.g. Equifax)
  10. TRUSTING CERTIFICATE AUTHORITIES Make sure you validate SSL certificates. Limit

    the authorities that you trust, if possible (but be aware that cross-signed roots can thwart this)
  11. SSL/TLS ˒  Is a pre y good, secure protocol... ˒ 

    ... if you use it correctly ... ˒  ... if you`re pedantic about checking for revoked certificates ... ˒  ... except if you trust the wrong CA`s ... ˒  ... except for the occasional design (or implementation) flaw ...
  12. LAYERED APPROACH TO SECURITY Where possible, build systems with multiple

    lines of defense - so even if one falls, all is not lost…
  13. LAYERED APPROACH TO SECURITY ˒  Example: Firefox Updates ˒  Firefox

    relied solely on SSL to authenticate browser updates ˒  In 2009, Moxie Marlinspike found a way to forge certificates, including for Mozilla`s update servers - could have tricked Firefox into auto- downloading malicious code. h p://safecomputing.umich.edu/events/sumit09/docs/Moxi%20more2.pdf
  14. HTTP BASIC $ python Python 2.7.1 (r271:86832, Jul 31 2011,

    19:30:53) ... >>> auth = "QWxhZGRpbjpvcGVuIHNlc2FtZQ==" >>> auth.decode('base64') 'Aladdin:open sesame' ... This might as well be plaintext!
  15. FLICKR API SIGNATURE (2009) ˒  Sort parameters alphabetically. Call the

    name of the first parameter key1, its value value1, and so on. ˒  Construct a string: tosign = SECRET + key1 + value1 + key2 + value2 + ... ˒  Compute: sig = md5(tosign) ˒  Append a parameter “api_sig” to the parameter list, with sig as its value.
  16. FLICKR API SIGNATURE (2009) ˒  Designed to be secure even

    without SSL ˒  Only signing the request parameters? ˒  Request is always a GET ˒  Request is always directed to one URL endpoint (API method specified as a parameter)
  17. FLICKR API SIGNATURE (2009) For an unsigned query string: “method=flickr.auth.getFrob&api_key=12345”

    We have: tosign = \ “SECRETapi_key12345methodflickr.auth.getFrob” sig = md5(tosign) # “b9195b9911e6a5c92efc50a31bû8bb7” Yielding the signed query string: “method=flickr.auth.getFrob&api_key=12345&api_sig= b9195b9911e6a5c92efc50a31bû8bb7”
  18. MD5 LENGTH EXTENSION ATTACK ˒  For a string m, if

    you know md5(m) and len(m), then you can compute md5(m + pad(m) + m’) for any new message m’ ˒  Flickr`s secrets were a fixed length; len(m) is trivial to calculate if you intercept an API request h p://netifera.com/research/flickr_api_signature_forgery.pdf
  19. MD5 LENGTH EXTENSION ATTACK ˒  If an a acker intercepts

    a signed request: api_key=12345&method=flickr.auth.getFrob&api_si g= b9195b9911e6a5c92efc50a31bû8bb7 ˒  Then, he could easily compute a valid signature for a request like: api_key=12345&method=flickr.auth.getFrob[PADDI NG]&sinister_param=foobar ˒  But this probably wouldn`t do much...?
  20. FLICKR API FAIL ˒  If an a acker intercepts a

    signed request: api_key=12345&method=flickr.auth.getFrob&api_si g=b9195b9911e6a5c92efc50a31bû8bb7 ˒  Then, he could sign another request: a=pi_key12345methodflickr.auth.getFrob[PADDIN G]&api_key=12345&method=do.something.EVIL ˒  If Flickr ignores the invalid ba` parameter, all is lost!
  21. NOT JUST FLICKR ˒  Scribd ˒  Vimeo ˒  Remember The

    Milk (not exploitable?) ˒  Amazon Web Services API v1 (missing delimiters, but no length extension) ˒  many others...
  22. LESSONS FROM FLICKR ˒  HMAC ˒  First published in 1996

    ˒  Designed specifically to avoid problems like length extension! ˒  Make sure the signature includes any necessary information about the structure of the message
  23. LESSONS FROM FLICKR Don`t design your own signature scheme (but

    also be careful when copying someone else’s!)
  24. GOOD: AWS SIGNATURE V2 Create a canonical representation of your

    request: GET /protected/resource example.com param1=value1&param2=value2&param3=value3 Then compute: sig = HMAC-SHA1(canonical_string, SECRET) h p://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/using-query-api.html
  25. REPLAY ATTACKS ˒  If an a acker captures an API

    request, he can still re-send it without modification ˒  (Imperfect) Solutions: ˒  Timestamp (e.g. AWS ‘Expires’ parameter) ˒  Nonce
  26. WORSE: AWS SIGNATURE V3 (?) ˒  HMAC of current time

    ˒  As useful to an a acker as a time-limited password ˒  “To avoid replays of your requests, AWS requires the time stamp in the request to be within 5 minutes of the AWS system time.”
  27. OAUTH ˒  Heavier-weight, but worth a look ˒  Defines external

    authentication/authorization architecture for your API ˒  Complicated to implement (but there are libraries)
  28. ENFORCING AUTHORIZATION ˒  Have a clear understanding of what information

    is secret and what is not ˒  Account IDs should not be considered secret... ˒  Make sure that users cannot access resources that are not theirs to access (no ma er how hidden they may otherwise be)
  29. EXAMPLE: RESPONSE CODES Client: GET /account/alice HTTP/1.1 Host: example.com Server:

    404 NOT FOUND What’s the difference? Client: GET /account/bob HTTP/1.1 Host: example.com Server: 401 UNAUTHORIZED
  30. EXAMPLE: RESPONSE CODES What’s the difference? ... Now we know

    an account named ‘bob’ exists! Client: GET /account/alice HTTP/1.1 Host: example.com Server: 404 NOT FOUND Client: GET /account/bob HTTP/1.1 Host: example.com Server: 401 UNAUTHORIZED
  31. EXAMPLE: RESPONSE CODES (unless the server is just messing with

    us – but it probably isn’t…) Client: GET /account/alice HTTP/1.1 Host: example.com Server: 404 NOT FOUND Client: GET /account/carol HTTP/1.1 Host: example.com Server: 418 I’M A TEAPOT
  32. INFORMATION LEAKAGE ˒  Don`t reveal anything unnecessarily ˒  Anything you

    say can and will be used against you :) ˒  (Need to balance this with usability)
  33. HASH TABLE $ python ... >>> phones = { ...

    'Bob': '555-1234', ... 'Jane': '555-9876', ... 'Mike': '555-2468' ... } >>> phones['Bob'] '555-1234'
  34. HASH TABLE Bob Jane ... 00 01 02 14 15

    555-1234 555-9876 Bob Jane Hash Function
  35. COLLISIONS Bob Jane ... 00 01 02 14 15 555-1234

    555-9876 Bob Jane Hash Function Mike Mike 555-2468
  36. WORST CASE Your hash table just became a linked list...

    Bob ... 00 01 02 555-1234 Bob Mike Hash Function Charlie Mike 555-2468 Charlie 555-3456 James 555-4567 James
  37. WORST CASE PHP 5 500 KB 60 seconds* ASP.NET 330

    KB 90 seconds* Tomcat (Java)† 2 MB* 44 minutes Plone (Python) 1 MB* 7 minutes Ruby 1.8† 2 MB* 6 hours h p://www.nruns.com/_downloads/advisory28122011.pdf * default limit enforced by web server † fixed in recent updates
  38. CLEVER NEW ATTACK? ˒  lDenial of service via algorithmic complexity

    a acksz ˒  Presented by Sco Crosby and Dan Wallach at Usenix Security in 2003! h p://www.cs.rice.edu/~scrosby/hash/CrosbyWallach_UsenixSec2003.pdf
  39. AVAILABILITY ˒  Place limits on the resources that a single

    request can consume ˒  CPU time ˒  Wall time ˒  Request size ˒  Consider making your API partition-tolerant ˒  customer1.yoursite.com, customer2.yoursite.com, ...