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 full-size slide

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

    View full-size slide

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

    View full-size slide

  4. osmihelp.org

    View full-size slide

  5. PROTECTING YOUR API

    THE PAST, THE PRESENT AND THE FUTURE
    ARMEN MKRTCHYAN

    View full-size slide

  6. AUTH CODE
    REFRESH_TOKEN
    ACCESS_TOKEN
    API KEY
    BEARER TOKEN
    ID_TOKEN

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  10. HTTP BASIC AUTH

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  13. 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 full-size slide

  14. 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 full-size slide

  15. 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 full-size slide

  16. 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 full-size slide

  17. 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 full-size slide

  18. 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 full-size slide

  19. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  22. LETS TALK ABOUT LEGS!

    View full-size slide

  23. 2-LEGGED/3-LEGGED
    AUTHENTICATION

    View full-size slide

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

    View full-size slide

  25. CLIENT_ID
    CLIENT_SECRET
    REDIRECT_URI
    GRANT_TYPES
    SCOPES
    CLIENT

    View full-size slide

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

    View full-size slide

  27. AUTHORIZATION CODE
    3-LEGGED

    View full-size slide

  28. 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 full-size slide

  29. 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 full-size slide

  30. CLIENT CREDENTIALS
    2-LEGGED

    View full-size slide

  31. 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 full-size slide

  32. USING ACCESS_TOKEN

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  35. SELF-INVENTED
    SOLUTIONS

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  39. RETROSPECTIVE

    View full-size slide

  40. 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 full-size slide

  41. 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 full-size slide

  42. OPENID CONNECT

    View full-size slide

  43. OAUTH2 + IDENTITY LAYER

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  46. WHAT CHANGED?

    View full-size slide

  47. 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 full-size slide

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

    View full-size slide

  49. {
    "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 full-size slide

  50. USERINFO ENDPOINT

    View full-size slide

  51. 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 full-size slide

  52. 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 full-size slide

  53. 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 full-size slide

  54. ARE WE THERE YET?

    View full-size slide

  55. EVERY TALK SHOULD
    DELIVER A MESSAGE

    View full-size slide

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

    View full-size slide

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

    View full-size slide