Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

2016 JavaOne Deconstructing REST Security

788 views

Published on

The learning curve for security is severe and unforgiving. Specifications promise infinite flexibility, habitually give old concepts new names, are riddled with extensions, and almost seem designed to deliberately confuse. For a back-end REST developer, choking all this down for the first time is mission impossible. With an aggressive distaste for fancy terminology, this session delves into OAuth 2.0 as it pertains to REST and shows how it falls into two camps: stateful and stateless. The presentation also details a competing Amazon-style approach called HTTP Signatures and digs into the architectural differences of all three, with a heavy focus on the wire, showing actual HTTP messages and enough detail to have you thinking, “I could write this myself.”

Published in: Software
  • Be the first to comment

2016 JavaOne Deconstructing REST Security

  1. 1. JavaOne #RESTSecurity @dblevins @tomitribe Deconstructing REST Security David Blevins Tomitribe
  2. 2. JavaOne #RESTSecurity @dblevins @tomitribe “The nice thing about standards is you have so many to choose from.” - Andrew S. Tanenbaum
  3. 3. JavaOne #RESTSecurity @dblevins @tomitribe Focus Areas • Beyond Basic Auth • Theory of OAuth 2.0 • Introduction of JWT • Google/Facebook style API security • Stateless vs Stateful Architecture • HTTP Signatures • Amazon EC2 style API security
  4. 4. JavaOne #RESTSecurity @dblevins @tomitribe Baseline Architecture 1000 users x 3 TPS 4 hops 3000 TPS frontend 12000 TPS backend
  5. 5. JavaOne #RESTSecurity @dblevins @tomitribe Basic Auth (and its problems)
  6. 6. JavaOne #RESTSecurity @dblevins @tomitribe Basic Auth Message POST /painter/color/object HTTP/1.1 Host: localhost:8443 Authorization: Basic c25vb3B5OnBhc3M= User-Agent: curl/7.43.0 Accept: */* Content-Type: application/json Content-Length: 45 {"color":{"b":255,"g":0,"name":"blue","r":0}}
  7. 7. JavaOne #RESTSecurity @dblevins @tomitribe Basic Auth Password Sent 3000 TPS (HTTP+SSL) username+password Base64 (no auth) 3000 TPS (LDAP) 12000 TPS (HTTP)
  8. 8. JavaOne #RESTSecurity @dblevins @tomitribe Basic Auth Password Sent 3000 TPS (HTTP+SSL) username+password Base64 username+password Base64 15000 TPS (LDAP) Password Sent 12000 TPS (HTTP)
  9. 9. JavaOne #RESTSecurity @dblevins @tomitribe Basic Auth Password Sent 3000 TPS (HTTP+SSL) username+password Base64 IP whitelisting 3000 TPS (LDAP) 12000 TPS (HTTP)
  10. 10. JavaOne #RESTSecurity @dblevins @tomitribe “Hey, give me all of Joe’s salary information.” “I don’t know who you are, … but sure!”
  11. 11. JavaOne #RESTSecurity @dblevins @tomitribe Latveria Attacks
  12. 12. JavaOne #RESTSecurity @dblevins @tomitribe Basic Auth - Attacks Valid Password Sent 3000 TPS (HTTP+SSL) IP whitelisting 9000 TPS (LDAP) 12000 TPS (HTTP) Invalid Password Sent 6000 TPS (HTTP+SSL)
  13. 13. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2.0 (and its problems)
  14. 14. JavaOne #RESTSecurity @dblevins @tomitribe
  15. 15. JavaOne #RESTSecurity @dblevins @tomitribe
  16. 16. JavaOne #RESTSecurity @dblevins @tomitribe
  17. 17. JavaOne #RESTSecurity @dblevins @tomitribe
  18. 18. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2 - Password Grant (LDAP) (Token Store) POST /oauth2/token Host: api.superbiz.io User-Agent: curl/7.43.0 Accept: */* Content-Type: application/x-www-form-urlencoded Content-Length: 54 grant_type=password&username=snoopy&password=woodstock HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", } Verify Password Generate Token
  19. 19. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2.0 Message POST /painter/color/object HTTP/1.1
 Host: api.superbiz.io
 Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
 User-Agent: curl/7.43.0
 Accept: */*
 Content-Type: application/json
 Content-Length: 45
 
 {"color":{"b":255,"g":0,"r":0,"name":"blue"}}
  20. 20. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2.0 Message POST /painter/color/palette HTTP/1.1
 Host: api.superbiz.io
 Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
 User-Agent: curl/7.43.0
 Accept: */*
 Content-Type: application/json
 Content-Length: 46
 
 {"color":{"b":0,"g":255,"r":0,"name":"green"}}
  21. 21. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2.0 Message POST /painter/color/select HTTP/1.1
 Host: api.superbiz.io
 Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
 User-Agent: curl/7.43.0
 Accept: */*
 Content-Type: application/json
 Content-Length: 44
 
 {"color":{"b":255,"g":0,"r":0,"name":"red"}}
  22. 22. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2.0 Message POST /painter/color/fill HTTP/1.1
 Host: api.superbiz.io
 Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
 User-Agent: curl/7.43.0
 Accept: */*
 Content-Type: application/json
 Content-Length: 49
 
 {"color":{"b":255,"g":255,"r":0,"name":"yellow"}}
  23. 23. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2.0 Message POST /painter/color/stroke HTTP/1.1
 Host: api.superbiz.io
 Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
 User-Agent: curl/7.43.0
 Accept: */*
 Content-Type: application/json
 Content-Length: 49
 
 {"color":{"b":255,"g":200,"r":0,"name":"orange"}}
  24. 24. JavaOne #RESTSecurity @dblevins @tomitribe 401
  25. 25. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2 - Refresh Grant (LDAP) (Token Store) Verify Password Generate Token POST /oauth2/token Host: api.superbiz.io User-Agent: curl/7.43.0 Accept: */* Content-Type: application/x-www-form-urlencoded Content-Length: 54 grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"6Fe4jd7TmdE5yW2q0y6W2w", "expires_in":3600, "refresh_token":"hyT5rw1QNh5Ttg2hdtR54e", }
  26. 26. JavaOne #RESTSecurity @dblevins @tomitribe Old pair • Access Token 2YotnFZFEjr1zCsicMWpAA • Refresh Token tGzv3JOkF0XG5Qx2TlKWIA New pair • Access Token 6Fe4jd7TmdE5yW2q0y6W2w • Refresh Token hyT5rw1QNh5Ttg2hdtR54e
  27. 27. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2.0 Message POST /painter/color/palette HTTP/1.1
 Host: api.superbiz.io
 Authorization: Bearer 6Fe4jd7TmdE5yW2q0y6W2w
 User-Agent: curl/7.43.0
 Accept: */*
 Content-Type: application/json
 Content-Length: 46
 
 {"color":{"b":0,"g":255,"r":0,"name":"green"}}
  28. 28. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2.0 Message POST /painter/color/select HTTP/1.1
 Host: api.superbiz.io
 Authorization: Bearer 6Fe4jd7TmdE5yW2q0y6W2w
 User-Agent: curl/7.43.0
 Accept: */*
 Content-Type: application/json
 Content-Length: 44
 
 {"color":{"b":255,"g":0,"r":0,"name":"red"}}
  29. 29. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2.0 Message POST /painter/color/fill HTTP/1.1
 Host: api.superbiz.io
 Authorization: Bearer 6Fe4jd7TmdE5yW2q0y6W2w
 User-Agent: curl/7.43.0
 Accept: */*
 Content-Type: application/json
 Content-Length: 49
 
 {"color":{"b":255,"g":255,"r":0,"name":"yellow"}}
  30. 30. JavaOne #RESTSecurity @dblevins @tomitribe What have we achieved?
  31. 31. JavaOne #RESTSecurity @dblevins @tomitribe You have more passwords (at least your devices do)
  32. 32. JavaOne #RESTSecurity @dblevins @tomitribe Term Alert • Password Grant??? • Logging in • Token? • Slightly less crappy password • Equally crappy HTTP Session ID
  33. 33. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2 Tokens Sent 3000 TPS (HTTP+SSL) IP whitelisting 3000 TPS (token checks) Password Sent 1000/daily (HTTP+SSL) OAuth 2 (LDAP) 4 hops 12000 TPS backend
  34. 34. JavaOne #RESTSecurity @dblevins @tomitribe
  35. 35. JavaOne #RESTSecurity @dblevins @tomitribe “Who the heck is 6Fe4jd7TmdE5y W2q0y6W2w ???????” “No idea, dude. Ask the token server.”
  36. 36. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2 Tokens Sent 3000 TPS (HTTP+SSL) IP whitelisting 3000 TPS (token checks) Password Sent 1000/daily (HTTP+SSL) OAuth 2 (LDAP) 12000 TPS (token checks) 8 hops 24000 TPS backend
  37. 37. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2 Tokens Sent 3000 TPS (HTTP+SSL) IP whitelisting 3000 TPS (token checks) Password Sent 1000/daily (HTTP+SSL) OAuth 2 (LDAP) 12000 TPS (token checks) 8 hops 24000 TPS backend 55% of all traffic
  38. 38. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2 Tokens Sent 3000 TPS (HTTP+SSL) IP whitelisting 0 TPS (token checks) Password Sent 1000/daily (HTTP+SSL) OAuth 2 (LDAP) 0 TPS (token checks) 0 hops 0 TPS backend
  39. 39. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2 Pointer Pointer State
  40. 40. JavaOne #RESTSecurity @dblevins @tomitribe Access Token Access Pointer? Access Primary Key?
  41. 41. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2.0 High Frequency Password Exchange Algorithm?
  42. 42. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2.0 + JSon Web Tokens (JWT)
  43. 43. JavaOne #RESTSecurity @dblevins @tomitribe JSon Web Token • Pronounced “JOT” • Fancy JSON map • Base64 URL Encoded • Digitally Signed (RSA-SHA256, HMAC-SHA512, etc) • Built-in expiration
  44. 44. JavaOne #RESTSecurity @dblevins @tomitribe Access Token Previously • 6Fe4jd7TmdE5yW2q0y6W2w
  45. 45. JavaOne #RESTSecurity @dblevins @tomitribe Access Token Now • eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbi10eXBlIjoi YWNjZXNzLXRva2VuIiwidXNlcm5hbWUiOiJzbm9vcHkiLCJhb mltYWwiOiJiZWFnbGUiLCJpc3MiOiJodHRwczovL2RlbW8uc3 VwZXJiaXouY29tL29hdXRoMi90b2tlbiIsInNjb3BlcyI6WyJ0d2l 0dGVyIiwibWFucy1iZXN0LWZyaWVuZCJdLCJleHAiOjE0NzQy ODA5NjMsImlhdCI6MTQ3NDI3OTE2MywianRpIjoiNjY4ODFi MDY4YjI0OWFkOSJ9.DTfSdMzIIsC0j8z3icRdYO1GaMGl6j1I_2 DBjiiHW9vmDz8OAw8Jh8DpO32fv0vICc0hb4F0QCD3KQnv8 GVM73kSYaOEUwlW0k1TaElxc43_Ocxm1F5IUNZvzlLJ_ksFXG DL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNo
  46. 46. JavaOne #RESTSecurity @dblevins @tomitribe Access Token Now • header (JSON > Base64 URL Encoded) • describes how the token signature can be checked • payload (JSON > Base64 URL Encoded) • Basically a map of whatever you want to put in it • Some standard keys such as expiration • signature (Binary > Base64 URL Encoded • The actual digital signature • made exclusively by the /oauth2/token endpoint • If RSA, can be checked by anyone
  47. 47. JavaOne #RESTSecurity @dblevins @tomitribe • { "alg": “RS256", "typ": “JWT" } • { "token-type": "access-token", "username": "snoopy", "animal": "beagle", "iss": "https://demo.superbiz.com/oauth2/token", "scopes": [ “twitter”, "mans-best-friend" ], "exp": 1474280963, "iat": 1474279163, "jti": "66881b068b249ad9" } • DTfSdMzIIsC0j8z3icRdYO1GaMGl6j1I_2DBjiiHW9vmDz8OAw8Jh8DpO32fv0vIC c0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1TaElxc43_Ocxm1F5IUNZvzlLJ_ks FXGDL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNo
  48. 48. JavaOne #RESTSecurity @dblevins @tomitribe Subtle But High Impact Architectural Change
  49. 49. JavaOne #RESTSecurity @dblevins @tomitribe What we had (quick recap)
  50. 50. JavaOne #RESTSecurity @dblevins @tomitribe (LDAP) Pull User Info From IDP
  51. 51. JavaOne #RESTSecurity @dblevins @tomitribe (LDAP) Generate an Access Token (pointer)
  52. 52. JavaOne #RESTSecurity @dblevins @tomitribe (LDAP) Insert both into DB
  53. 53. JavaOne #RESTSecurity @dblevins @tomitribe (LDAP) Send Access Token (pointer) to client
  54. 54. JavaOne #RESTSecurity @dblevins @tomitribe Results Client Holds Pointer Server Holds State
  55. 55. JavaOne #RESTSecurity @dblevins @tomitribe What we can do now (Hello JWT!)
  56. 56. JavaOne #RESTSecurity @dblevins @tomitribe (LDAP) Pull User Info From IDP
  57. 57. JavaOne #RESTSecurity @dblevins @tomitribe (LDAP) Format the data as JSON
  58. 58. JavaOne #RESTSecurity @dblevins @tomitribe (LDAP) RSA-SHA 256 sign JSON
  59. 59. JavaOne #RESTSecurity @dblevins @tomitribe (LDAP) Insert only pointer into DB (for revocation)
  60. 60. JavaOne #RESTSecurity @dblevins @tomitribe (LDAP) Send Access Token (state) to client
  61. 61. JavaOne #RESTSecurity @dblevins @tomitribe Client Holds State Server Holds Pointer Desired Results
  62. 62. JavaOne #RESTSecurity @dblevins @tomitribe
  63. 63. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2 - Password Grant (LDAP) (Token ID Store) POST /oauth2/token Host: api.superbiz.io User-Agent: curl/7.43.0 Accept: */* Content-Type: application/x-www-form-urlencoded Content-Length: 54 grant_type=password&username=snoopy&password=woodstock Verify Password Generate Signed Token HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9. eyJ0b2tlbi10eXBlIjoiYWNjZXNzLXRva2VuIiwidXNlcm5hb WUiOiJzbm9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3M iOiJodHRwczovL2RlbW8uc3VwZXJiaXouY29tL29hdXRoM i90b2tlbiIsInNjb3BlcyI6WyJ0d2l0dGVyIiwibWFucy1iZXN0 LWZyaWVuZCJdLCJleHAiOjE0NzQyODA5NjMsImlhdCI6M TQ3NDI3OTE2MywianRpIjoiNjY4ODFiMDY4YjI0OWFkOSJ 9.DTfSdMzIIsC0j8z3icRdYO1GaMGl6j1I_2DBjiiHW9vmDz8 OAw8Jh8DpO32fv0vICc0hb4F0QCD3KQnv8GVM73kSYaO EUwlW0k1TaElxc43_Ocxm1F5IUNZvzlLJ_ksFXGDL_cuadh VDaiqmhct098ocefuv08TdzRxqYoEqYNo", "expires_in":3600, "refresh_token":"eyJhbGctGzv3JOkF0XG5Qx2TlKWIAkF0X. eyJ0b2tlbi10eXBlIjoiYWNjZXNzLXRva2VuIiwidXNlcm5hb WUiOiJzbm9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3M iOiJodHRwczovL", }
  64. 64. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2.0 Message with JWT POST /painter/color/palette HTTP/1.1
 Host: api.superbiz.io
 Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbi10eXBlIjoiYWNjZXNzLXR va2VuIiwidXNlcm5hbWUiOiJzbm9vcHkiLCJhbmltYWwiOiJiZWFnbGUiLCJpc3MiOiJodHRwczovL2RlbW8uc3VwZXJ iaXouY29tL29hdXRoMi90b2tlbiIsInNjb3BlcyI6WyJ0d2l0dGVyIiwibWFucy1iZXN0LWZyaWVuZCJdLCJleHAiOjE0NzQy ODA5NjMsImlhdCI6MTQ3NDI3OTE2MywianRpIjoiNjY4ODFiMDY4YjI0OWFkOSJ9.DTfSdMzIIsC0j8z3icRdYO1GaMGl 6j1I_2DBjiiHW9vmDz8OAw8Jh8DpO32fv0vICc0hb4F0QCD3KQnv8GVM73kSYaOEUwlW0k1TaElxc43_Ocxm1F5IUNZ vzlLJ_ksFXGDL_cuadhVDaiqmhct098ocefuv08TdzRxqYoEqYNo User-Agent: curl/7.43.0
 Accept: */*
 Content-Type: application/json
 Content-Length: 46
 
 {"color":{"b":0,"g":255,"r":0,"name":"green"}}
  65. 65. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2 + JWT Tokens Sent 3000 TPS (HTTP+SSL) IP whitelisting 0.55 TPS (refresh token checks) Password Sent 1000/daily (HTTP+SSL) OAuth 2 (LDAP) 4 hops 12000 TPS backend 3000 TPS (signature verification) 12000 TPS (signature verification)
  66. 66. JavaOne #RESTSecurity @dblevins @tomitribe “Hey, give me all of Joe’s salary information.” “Not a chance!”
  67. 67. JavaOne #RESTSecurity @dblevins @tomitribe “Hey, give me all of Joe’s salary information.” “Sure thing!”
  68. 68. JavaOne #RESTSecurity @dblevins @tomitribe OAuth 2 + JWT Valid Tokens Sent 3000 TPS (HTTP+SSL) IP whitelisting 0.55 TPS (refresh token checks) Password Sent 1000/daily (HTTP+SSL) (LDAP) 4 hops 12000 TPS backend 9000 TPS (signature verification) 12000 TPS (signature verification) Invalid Tokens Sent 6000 TPS (HTTP+SSL)
  69. 69. JavaOne #RESTSecurity @dblevins @tomitribe http://connect2id.com/products/nimbus-jose-jwt Great JWT lib
  70. 70. JavaOne #RESTSecurity @dblevins @tomitribe HTTP Signatures (Amazon EC2 style API Security)
  71. 71. JavaOne #RESTSecurity @dblevins @tomitribe HTTP Signatures • No “secret” ever hits the wire • Signs the message itself • Proves identity • Prevents message tampering • Symmetric or Asymmetric signatures • IETF Draft • https://tools.ietf.org/html/draft-cavage-http-signatures • Extremely simple • Does NOT eliminate benefits of JWT (they’
  72. 72. JavaOne #RESTSecurity @dblevins @tomitribe Signature Message POST /painter/color/palette HTTP/1.1
 Host: api.superbiz.io
 Authorization: Signature keyId=“my-key-name", algorithm="hmac-sha256", headers="content-length host date (request-target)”, signature="j050ZC4iWDW40nVx2oVwBEymXzwvsgm+hKBkuw04b+w="
 Date: Mon, 19 Sep 2016 16:51:35 PDT Accept: */*
 Content-Type: application/json
 Content-Length: 46
 
 {"color":{"b":0,"g":255,"r":0,"name":"green"}}
  73. 73. JavaOne #RESTSecurity @dblevins @tomitribe Signature Auth Password Sent 0 TPS (HTTP) Signature (no auth) 3000 TPS (LDAP or Keystore) 12000 TPS (HTTP)
  74. 74. JavaOne #RESTSecurity @dblevins @tomitribe Signature Auth Password Sent 0 TPS (HTTP) Signature Signature 3000 TPS (LDAP or Keystore) 12000 TPS (HTTP)
  75. 75. JavaOne #RESTSecurity @dblevins @tomitribe “Hey, give me all of Joe’s salary information.” “Hey, Larry! Sure!”
  76. 76. JavaOne #RESTSecurity @dblevins @tomitribe OAuth and Signatures Password Sent 3000 TPS (HTTP+SSL) OAuth 2 Signature 12000 TPS (HTTP)
  77. 77. JavaOne #RESTSecurity @dblevins @tomitribe “Hey, give me all of Joe’s salary information.” “Sure thing, Larry! Tell Joe I said hi.”
  78. 78. JavaOne #RESTSecurity @dblevins @tomitribe OAuth and Signatures Password Sent 3000 TPS (HTTP+SSL) OAuth 2 Signature 12000 TPS (HTTP) Joe Larry Stan
  79. 79. JavaOne #RESTSecurity @dblevins @tomitribe Observations • HTTP Signatures the only HTTP friendly approach • Signatures does not solve the “Identity Load” problem • OAuth 2 with JWT significantly improves IDP load • Plain OAuth 2 • HTTP Session-like implications • OAuth 2 with JWT • Signed cookie • Signing key to the future
  80. 80. JavaOne #RESTSecurity @dblevins @tomitribe Thank You!

×