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

Api Protection

Api Protection

Building a secure API is one of the most common requirements in the market nowadays. Yet there are many strategies with their strengths and fallbacks, some simple, some complex. Let’s together walk through the existing strategies and take a look at a solution, that could, potentially, end this discussion once and for all.

Armen Mkrtchyan

October 27, 2017
Tweet

More Decks by Armen Mkrtchyan

Other Decks in Technology

Transcript

  1. PROTECTING YOUR API

    THE PAST, THE PRESENT AND THE FUTURE
    ARMEN MKRTCHYAN

    View Slide

  2. View Slide

  3. ARMEN MKRTCHYAN
    @IAMTANKIST
    (github, twitter, telegram)

    View Slide

  4. YOU CAN WRITE A LOT
    OF TEXT ON BLACK
    BACKGROUND HERE.

    View Slide

  5. View Slide

  6. osmihelp.org

    View Slide

  7. PROTECTING YOUR API

    THE PAST, THE PRESENT AND THE FUTURE
    ARMEN MKRTCHYAN

    View Slide

  8. AUTH CODE
    REFRESH_TOKEN
    ACCESS_TOKEN
    API KEY
    BEARER TOKEN
    ID_TOKEN

    View Slide

  9. AUTH CODE
    REFRESH_TOKEN
    ACCESS_TOKEN
    API KEY
    BEARER TOKEN
    ID_TOKEN
    TOKEN?

    View Slide

  10. TOKEN WILLIAMS
    Aliases Blackie
    Gender Male
    Hair Black
    Age 10
    Occupation Student
    Grade 4th Grade

    View Slide

  11. noun to·ken \ ˈtō-kən \
    TOKEN
    „something given or shown as a guarantee (as of
    authority, right, or identity)“

    View Slide

  12. View Slide

  13. HTTP BASIC AUTH

    View Slide

  14. $ sudo htpasswd -c /etc/apache2/.htpasswd user1
    $ cat /etc/apache2/.htpasswd
    user1:$apr1$/woC1jnP$KAh0SsVn5qeSMjTtn0E9Q0
    STEP 1

    View Slide

  15. STEP 2 - NGINX CONFIGURATION
    ...
    http {
    server {
    location /foo/bar {
    auth_basic "Protected Area";
    auth_basic_user_file /etc/apache2/.htpasswd;
    }
    }
    }
    ...

    View Slide

  16. STEP 3 - USE
    Access url in the browser - fill in the dialog
    base64_encode('user:password') => d3BhbG1lcjp0ZXN0dGVzdA==
    GET / HTTP/1.1

    Host: example.com

    Authorization: Basic d3BhbG1lcjp0ZXN0dGVzdA==
    // embed in URL

    https://user:[email protected]
    2
    1
    3

    View Slide

  17. STEP 3 - USE
    Access url in the browser - fill in the dialog
    base64_encode('user:password') => d3BhbG1lcjp0ZXN0dGVzdA==
    GET / HTTP/1.1

    Host: example.com

    Authorization: Basic d3BhbG1lcjp0ZXN0dGVzdA==
    // embed in URL

    https://user:[email protected]
    2
    1
    3

    View Slide

  18. OAUTH 1

    View Slide

  19. STEP 1 - INITIALISE
    POST /initiate HTTP/1.1

    Host: photos.example.net

    Authorization: OAuth realm="Photos", \

    oauth_consumer_key="dpf43f3p2l4k3l03", \

    oauth_signature_method="HMAC-SHA1", \

    oauth_timestamp="137131200", \

    oauth_nonce="wIjqoS", \

    oauth_callback="http%3A%2F%2Fclient.example.com%2Fready", \

    oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D" \
    HTTP/1.1 200 OK

    Content-Type: application/x-www-form-urlencoded

    oauth_token=hh5s93j4hdidpola&

    oauth_token_secret=hdhd0244k9j7ao03&

    oauth_callback_confirmed=true

    View Slide

  20. STEP 1 - INITIALISE
    POST /initiate HTTP/1.1

    Host: photos.example.net

    Authorization: OAuth realm="Photos", \

    oauth_consumer_key="dpf43f3p2l4k3l03", \

    oauth_signature_method="HMAC-SHA1", \

    oauth_timestamp="137131200", \

    oauth_nonce="wIjqoS", \

    oauth_callback="http%3A%2F%2Fclient.example.com%2Fready", \

    oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D" \
    HTTP/1.1 200 OK

    Content-Type: application/x-www-form-urlencoded

    oauth_token=hh5s93j4hdidpola&

    oauth_token_secret=hdhd0244k9j7ao03&

    oauth_callback_confirmed=true

    View Slide

  21. STEP 2 - AUTHORIZATION
    GET /authorize?oauth_token=hh5s93j4hdidpola HTTP/1.1

    Host: photos.example.net
    // Asks for username and login and redirects to
    http://? \

    oauth_token=hh5s93j4hdidpola& \

    oauth_verifier=hfdp7dh39dks9884

    View Slide

  22. STEP 3 - TOKEN
    POST /token HTTP/1.1
    Host: photos.example.net
    Authorization: OAuth realm="Photos",
    oauth_consumer_key="dpf43f3p2l4k3l03", \
    oauth_token="hh5s93j4hdidpola", \
    oauth_signature_method="HMAC-SHA1", \
    oauth_timestamp="137131201", \
    oauth_nonce="walatlh", \
    oauth_verifier="hfdp7dh39dks9884", \
    oauth_signature="gKgrFCywp7rO0OXSjdot%2FIHF7IU%3D"
    // redirects back with to
    http://? \
    oauth_token=hh5s93j4hdidpola& \
    oauth_verifier=hfdp7dh39dks9884

    View Slide

  23. STEP 4 - USING TOKEN
    GET /photos?file=vacation.jpg&size=original HTTP/1.1
    Host: photos.example.net
    Authorization: OAuth realm="Photos",
    oauth_consumer_key="dpf43f3p2l4k3l03",
    oauth_token="nnch734d00sl2jdk",
    oauth_signature_method="HMAC-SHA1",
    oauth_timestamp="137131202",
    oauth_nonce="chapoH",
    oauth_signature="MdpQcU8iPSUjWoN%2FUDMsK2sui9I%3D"

    View Slide

  24. OAUTH 2

    View Slide

  25. • More OAuth Flows
    • No client-side cryptography
    • Expiration of access_tokens

    View Slide

  26. CLIENTS
    SERVICE
    Users
    Admins
    Services
    3rd-Party
    Services
    Monitoring
    Things

    View Slide

  27. LETS TALK ABOUT LEGS!

    View Slide

  28. View Slide

  29. 2-LEGGED/3-LEGGED
    AUTHENTICATION

    View Slide

  30. View Slide

  31. View Slide

  32. 3-LEGGED 2-LEGGED
    SERVICE
    Users
    Admins
    Services
    3rd-Party
    Services
    Monitoring
    Things

    View Slide

  33. CLIENT_ID
    CLIENT_SECRET
    REDIRECT_URI
    GRANT_TYPES
    SCOPES
    CLIENT

    View Slide

  34. AUTHORIZATION CODE
    CLIENT CREDENTIALS
    PASSWORD
    IMPLICIT
    REFRESH
    CUSTOM
    GRANT TYPES
    ACCESS_TOKEN

    View Slide

  35. AUTHORIZATION CODE
    3-LEGGED

    View Slide

  36. AUTHORIZAION CODE - STEP 1
    POST /authorize HTTP/1.1
    Host: photos.example.net
    Content-Type: application/x-www-form-urlencoded
    response_type=code& \
    client_id=CLIENT_ID& \
    redirect_uri=https://client.example.com/cb& \
    scope=email,birthday& \
    state=csrf_string
    // Asks for user authorisation and redirects back
    HTTP/1.1 302 Found
    Location: https://client.example.com/cb?code=CODE&state=csrf_string

    View Slide

  37. AUTHORIZAION CODE - STEP 2
    POST /token HTTP/1.1
    Host: photos.example.net
    Content-Type: application/x-www-form-urlencoded
    grant_type=authorization_code& \
    code=CODE& \
    redirect_uri=https://client.example.com/cb& \
    client_id=CLIENT_id&
    Content-Type: application/json;charset=UTF-8
    {
    "access_token":"2YotnFZFEjr1zCsicMWpAA",
    "expires_in":3600,
    "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
    }

    View Slide

  38. CLIENT CREDENTIALS
    2-LEGGED

    View Slide

  39. POST /token HTTP/1.1
    Host: photos.example.net
    Content-Type: application/x-www-form-urlencoded
    grant_type=client_credentials& \
    client_id=CLIENT_id& \
    client_secret=CLIENT_SECRET
    Content-Type: application/json;charset=UTF-8
    {
    "access_token":"2YotnFZFEjr1zCsicMWpAB",
    "expires_in":3600
    }

    View Slide

  40. USING ACCESS_TOKEN

    View Slide

  41. GET /photos HTTP/1.1
    Host: photos.example.net
    Authorization: Bearer 2YotnFZFEjr1zCsicMWpAB

    View Slide

  42. GET /photos HTTP/1.1
    Host: photos.example.net
    Authorization: Bearer 2YotnFZFEjr1zCsicMWpAB

    View Slide

  43. SELF-INVENTED
    SOLUTIONS

    View Slide

  44. View Slide

  45. JWT

    View Slide

  46. View Slide

  47. • ISS - ISSUER (AKA ORIGIN)
    • SUB - SUBJECT (AKA USER_ID)
    • AUD - AUDIENCE (AKA CLIENT_ID)
    • EXP - EXPIRES AT
    • IAT - ISSUED AT
    JWT STANDARD CLAIMS

    View Slide

  48. View Slide

  49. lexik/LexikJWTAuthenticationBundle
    POST /users/login?_username=...&_password=... HTTP/1.1
    {token: "eyJhbGciOiJ..."}
    POST /photos HTTP/1.1
    Authorization: Bearer eyJhbGciOiJ...

    View Slide

  50. lexik/LexikJWTAuthenticationBundle
    POST /users/login?_username=...&_password=... HTTP/1.1
    {token: "eyJhbGciOiJ..."}
    POST /photos HTTP/1.1
    Authorization: Bearer eyJhbGciOiJ...

    View Slide

  51. RETROSPECTIVE

    View Slide

  52. BASIC AUTH - NICE, PASS INVOLVED
    OAUTH1 - TOO COMPLEX
    OAUTH2 - SOLVES THE PROBLEM, BUT...
    SELF-INVENTED - NO*
    JWT - OVER-SIMPLISTIC
    *unless you really know what you are doing

    View Slide

  53. 37signals, Asana, Amazon, Auth0, Azure, Bitbucket,
    Bitly, BufferApp, Clever, DeviantArt, Discogs,
    Disqus, Dropbox, EVE Online, Eventbrite, Facebook,
    FI-WARE, Flickr, Foursquare, GitHub, GitLab,
    Google, Hubic, Instagram, itembase, Jira, Linkedin,
    Mail.ru, Odnoklassniki, PayPal, QQ, Reddit,
    Salesforce, SensioLabs Connect, Sina Weibo, Spotify,
    Soundcloud, Stack Exchange, Stereomood, Strava,
    Toshl, Trello, Twitch, Twitter, Wunderlist,
    Vkontakte, Windows Live, XING, Yahoo, Yandex
    HTTPS://GITHUB.COM/HWI/
    HWIOAUTHBUNDLE

    View Slide

  54. OPENID CONNECT

    View Slide

  55. OAUTH2 + IDENTITY LAYER

    View Slide

  56. OAUTH2 + IDENTITY LAYER
    DISCOVERY
    DYNAMIC CLIENT REGISTRATION
    IMPLEMENTATION CERTIFICATION
    ID_TOKEN STANDARD CLAIMS
    SESSION MANAGEMENT
    JWKS
    FORM POST RESPONSE MODE

    View Slide

  57. View Slide

  58. View Slide

  59. AUTH0
    DEUTSCHE TELEKOM
    GOOGLE
    MICROSOFT
    PAYPAL
    PRO7SAT1
    RED HAT
    SALESFORCE
    SYMANTEC
    VERIZON

    View Slide

  60. WHAT CHANGED?

    View Slide

  61. AUTHORIZAION CODE - STEP 1
    POST /authorize HTTP/1.1
    Host: photos.example.net
    Content-Type: application/x-www-form-urlencoded
    response_type=code& \
    client_id=CLIENT_ID& \
    redirect_uri=https://client.example.com/cb& \
    scope=email,birthday,openid& \
    state=csrf_string
    // Asks for user authorisation and redirects back
    HTTP/1.1 302 Found
    Location: https://client.example.com/cb?code=CODE&state=csrf_string

    View Slide

  62. View Slide

  63. {
    "access_token": "SlAV3...2hkKG",
    "token_type": "Bearer",
    "refresh_token": "8xLO...xBtZp8",
    "expires_in": 3600,
    "id_token": "eyJhbGci...OiJS.UzI1...ImtpZCI6.IjFlOWdkaz...cifQewo"
    }

    View Slide

  64. {
    "iss": "http://server.example.com",
    "sub": "248289761001", // aka user_id
    "aud": "s6BhdRkqt3", // aka client_id
    "nonce": "n-0S6_WzA2Mj", // aka CSRF token
    "exp": 1311281970,
    "iat": 1311280970
    }

    View Slide

  65. USERINFO ENDPOINT

    View Slide

  66. GET /userinfo HTTP/1.1
    Authorization: Bearer SlAV3...2hkKG
    {
    "sub": "248289761001",
    "name": "Jane Doe",
    "given_name": "Jane",
    "family_name": "Doe",
    "preferred_username": "j.doe",
    "email": "[email protected]",
    "picture": "http://example.com/janedoe/me.jpg"
    }
    IT'S A STANDARD!!! (SECTION 5.2)

    View Slide

  67. GET /userinfo HTTP/1.1
    Authorization: Bearer SlAV3...2hkKG
    {
    "sub": "248289761001",
    "name": "Jane Doe",
    "given_name": "Jane",
    "family_name": "Doe",
    "preferred_username": "j.doe",
    "email": "[email protected]",
    "picture": "http://example.com/janedoe/me.jpg"
    }

    View Slide

  68. DISCOVERY

    View Slide

  69. GET /.well-known/openid-configuration HTTP/1.1
    Host: accounts.google.com
    Authorization: Bearer SlAV3...2hkKG
    {
    "issuer": "https://accounts.google.com",
    "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
    "token_endpoint": "https://www.googleapis.com/oauth2/v4/token",
    "userinfo_endpoint": "https://www.googleapis.com/oauth2/v3/userinfo",
    "revocation_endpoint": "https://accounts.google.com/o/oauth2/revoke",
    "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
    "response_types_supported": [
    "code", "token", "id_token", "code token", "code id_token",
    "token id_token", "code token id_token", "none"
    ],
    "scopes_supported": [ "openid", "email", "profile" ],
    "claims_supported": [
    "aud", "email", "email_verified", "exp", "family_name",
    "given_name", "iat", "iss", "locale", "name", "picture", "sub"
    ]
    }

    View Slide

  70. ARE WE THERE YET?

    View Slide

  71. View Slide

  72. EVERY TALK SHOULD
    DELIVER A MESSAGE

    View Slide

  73. „I might be no body,
    but wait ‘til I’m together like a symphony.“
    – IMMORTAL TECHNIQUE – “THE PROPHECY”

    View Slide

  74. THANK YOU!
    PLEASE GIVE ME SOME FEEDBACK!
    @IAMTANKIST
    (github, twitter, telegram)

    View Slide