Slide 1

Slide 1 text

Adam Goodman PUTTING WEB API SECURITY ISSUES TO REST

Slide 2

Slide 2 text

REST? h p://www.etsy.com/listing/85275007/soap-sleeping-ki en-soap-pink-relaxing

Slide 3

Slide 3 text

REINVENTING THE WHEEL h p://www.flickr.com/photos/vrogy/514733529/

Slide 4

Slide 4 text

INFORMATION SECURITY ˒  Confidentiality ˒  Authenticity ˒  Integrity ˒  Availability ˒  (...)

Slide 5

Slide 5 text

CONFIDENTIALITY

Slide 6

Slide 6 text

AUTHENTICITY h p://www.pxleyes.com/photoshop-contest/6964/zip-it.html

Slide 7

Slide 7 text

INTEGRITY

Slide 8

Slide 8 text

AVAILABILITY h p://www.flickr.com/photos/mr_t_in_dc/4264146249/

Slide 9

Slide 9 text

SSL/TLS ˒  Designed to guarantee all of: ˒  Confidentiality ˒  Integrity ˒  Authenticity

Slide 10

Slide 10 text

SSL CERTIFICATE

Slide 11

Slide 11 text

ASIDE: CHAIN OF TRUST Root Authority Intermediate Authority Intermediate Authority example.com SSL/TLS Client

Slide 12

Slide 12 text

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?

Slide 13

Slide 13 text

BUT...

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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.

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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?

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Y U NO VALIDATE?

Slide 22

Slide 22 text

CERTIFICATE AUTHORITY FAIL h p://www.infoworld.com/d/security/hackers-target-google-skype-rogue-ssl-certificates-603

Slide 23

Slide 23 text

CERTIFICATE AUTHORITY FAIL h p://www.scmagazine.com/diginotar-breach-fallout-widens-as-more-details-emerge/article/211349/

Slide 24

Slide 24 text

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)

Slide 25

Slide 25 text

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)

Slide 26

Slide 26 text

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 ...

Slide 27

Slide 27 text

LAYERED APPROACH TO SECURITY Where possible, build systems with multiple lines of defense - so even if one falls, all is not lost…

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

LAYERED APPROACH TO SECURITY ˒  Example: Firefox Updates ˒  Now, Firefox update payloads are signed, too.

Slide 30

Slide 30 text

AUTHENTICATION (from h p://www.youtube.com/watch?v=N7L5RjiCM-c)

Slide 31

Slide 31 text

HTTP BASIC GET /protected_resource HTTP/1.1 Host: example.com Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Slide 32

Slide 32 text

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!

Slide 33

Slide 33 text

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.

Slide 34

Slide 34 text

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)

Slide 35

Slide 35 text

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”

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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...?

Slide 38

Slide 38 text

NO DELIMITERS! ˒  Consider: ˒  lfoo=bar&greeting=hiz ˒  lf=oobargreetinghiz ˒  For both of these: ˒  tosign = “SECRETfoobargreetinghi”

Slide 39

Slide 39 text

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!

Slide 40

Slide 40 text

NOT JUST FLICKR ˒  Scribd ˒  Vimeo ˒  Remember The Milk (not exploitable?) ˒  Amazon Web Services API v1 (missing delimiters, but no length extension) ˒  many others...

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

LESSONS FROM FLICKR Don`t design your own signature scheme (but also be careful when copying someone else’s!)

Slide 43

Slide 43 text

GOOD: AWS SIGNATURE V2 Create a canonical representation of your request: GET /protected/resource example.com param1=value1¶m2=value2¶m3=value3 Then compute: sig = HMAC-SHA1(canonical_string, SECRET) h p://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/using-query-api.html

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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.”

Slide 46

Slide 46 text

OAUTH ˒  Heavier-weight, but worth a look ˒  Defines external authentication/authorization architecture for your API ˒  Complicated to implement (but there are libraries)

Slide 47

Slide 47 text

AUTHORIZATION

Slide 48

Slide 48 text

CITIGROUP FAIL h p://www.wired.com/threatlevel/2011/06/citibank-hacked/

Slide 49

Slide 49 text

CITIGROUP FAIL h p://www.theinquirer.net/inquirer/news/2079431/citibank-hacked-altering-urls

Slide 50

Slide 50 text

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)

Slide 51

Slide 51 text

INFORMATION LEAKAGE (The SQRT function)

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

INFORMATION LEAKAGE ˒  Don`t reveal anything unnecessarily ˒  Anything you say can and will be used against you :) ˒  (Need to balance this with usability)

Slide 56

Slide 56 text

BONUS: HASH TABLE DENIAL-OF-SERVICE h p://www.flickr.com/photos/joyosity/3357796927/

Slide 57

Slide 57 text

HASH TABLE POST /api/method HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded Content-Length: ... ... param1=value1¶m2=value2¶m3=value3&...

Slide 58

Slide 58 text

HASH TABLE $ python ... >>> phones = { ... 'Bob': '555-1234', ... 'Jane': '555-9876', ... 'Mike': '555-2468' ... } >>> phones['Bob'] '555-1234'

Slide 59

Slide 59 text

HASH TABLE Bob Jane ... 00 01 02 14 15 555-1234 555-9876 Bob Jane Hash Function

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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, ...

Slide 65

Slide 65 text

QUESTIONS? ˒  Email: [email protected] ˒  Twi er: @akgood