Share
Embed
Auth 101 - Longhorn PHP
Auth; almost every application employs it. From verifying that a user is who they say they are, to restricting access to a protected resource. If your application isn’t secure, there’s a lot to lose. Let’s learn the difference between authentication and authorisation, and the best ways to implement them.
Katy Ereira
November 09, 2022
Transcript
82 slides
-
@maccath | Katy Ereira | #LonghornPHP Auth 101. What even
is Auth anyway? -
@maccath | Katy Ereira | #LonghornPHP What do we mean
by ‘auth’? • Authentication? • Authorisation? • What’s the difference? -
@maccath | Katy Ereira | #LonghornPHP Authentication vs Authorisation Authentication
(authn) is used to determine that… • Your identity can be verified • Your credentials match what is held on file • Your request is authentic -
@maccath | Katy Ereira | #LonghornPHP Authentication vs Authorisation Authorisation
(authz) is used to determine that… • You are admitted entry to a protected area • You possess the correct key • You are permitted access to a resource • You have been authorised to perform an action -
@maccath | Katy Ereira | #LonghornPHP Remember: Authentication leads to
authorisation, but authorisation never leads to authentication. -
@maccath | Katy Ereira | #LonghornPHP Something You Know •
A username and password • A PIN • Answer to a secret question -
@maccath | Katy Ereira | #LonghornPHP Something You Have •
A key • A certificate • Access to a smart device • An email address or phone number -
@maccath | Katy Ereira | #LonghornPHP Something You Are •
Biometrics: fingerprints, voice, retina • Location-based • Facial recognition -
@maccath | Katy Ereira | #LonghornPHP Let’s talk about password
security… • Passwords must be strong • Passwords must be hashed and salted before storing • Passwords should not be the only authentication factor -
@maccath | Katy Ereira | #LonghornPHP Salting & hashing a
password <?php $password = $_POST['password']; // The plaintext password. $algorithm = PASSWORD_DEFAULT; // Choose an algorithm. $hash = password_hash($password, $algorithm); // Hash and salt it. // You may now store the value of $hash in your database! save-password.php -
@maccath | Katy Ereira | #LonghornPHP The Password Hash Function
• Creates a salt automatically so you don’t have to! • Returns the salt in the hash so no separate storage required. • Hash contains the algorithm parameters used to generate it. $2y$07$CCk9VkXcWxRIhy90tY21SeYjnHxoe0t/8.XQ3IV5KEelwrFTNu4Ge -
@maccath | Katy Ereira | #LonghornPHP Supported Algorithms • password_hash()
only supports strong hashing algorithms. • PASSWORD_DEFAULT is the PHP default algorithm; this can change if something stronger comes along. Currently, it is PASSWORD_BCRYPT • You can also use PASSWORD_ARGON2I and PASSWORD_ARGON2ID if PHP was compiled with Argon2 support. -
@maccath | Katy Ereira | #LonghornPHP Verifying a password <?php
$password = $_POST['password']; // The plaintext password /** @var object{hash: string} $user */ $hash = $user->hash; // The stored password hash $valid = password_verify($password, $hash); verify-password.php -
@maccath | Katy Ereira | #LonghornPHP Bonus points - rehashing!
// … cont’d if ($valid && password_needs_rehash($hash, PASSWORD_DEFAULT)) { // Create a new hash, and replace the old one $user->hash = password_hash($password, PASSWORD_DEFAULT); } verify-password.php -
@maccath | Katy Ereira | #LonghornPHP Application User credentials Auth
Handler Action Error 401 Password Verify -
@maccath | Katy Ereira | #LonghornPHP Multi-factor Authentication / 2FA
Anyone can obtain and use a password; it doesn’t verify anything! Two or more different authentication factors goes much further in determining the authenticity of a user. -
@maccath | Katy Ereira | #LonghornPHP Application User Action Error
401 Auth Handler credentials answer Password Verify Challenge Verify -
@maccath | Katy Ereira | #LonghornPHP Challenge Ideas • TOTP
- Time-based One Time Password • Email confirmation link • SMS OTP -
@maccath | Katy Ereira | #LonghornPHP Remember: Passwords verify nothing;
use two or more factors to really authenticate your users! -
@maccath | Katy Ereira | #LonghornPHP Using Sessions A session
is a way of persisting data between requests. Session data is stored server-side. When a session is created in PHP, a random session ID is generated. The ID is stored in a `PHPSESSID` cookie. -
@maccath | Katy Ereira | #LonghornPHP Application Auth Handler User
Action Error 401 Create Session Verify req. with credentials resp. with session ID Session Store -
@maccath | Katy Ereira | #LonghornPHP Creating a logged in
session <?php // ...cont’d $valid = password_verify($password, $hash); if ($valid) { session_start(); $_SESSION['loggedIn'] = true; } login.php -
@maccath | Katy Ereira | #LonghornPHP Application Auth Handler User
Action Error 401 Update Session Check Session req. with session ID Session Store -
@maccath | Katy Ereira | #LonghornPHP Checking if a user
is logged in <?php session_start(); if ($_SESSION['loggedIn'] === true) { // User is logged in! } login.php -
@maccath | Katy Ereira | #LonghornPHP Logging out <?php session_start();
unset($_SESSION['loggedIn']); // User is no longer logged in! logout.php -
@maccath | Katy Ereira | #LonghornPHP “ Using JWTs JSON
Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties. Reference: https:/ /jwt.io/ -
@maccath | Katy Ereira | #LonghornPHP Using JWTs A JWT
contains data, similar to the data a PHP Session might contain. The difference is that JWTs do not require server storage. Using a shared secret, JWTs can be decoded and validated across multiple services. -
@maccath | Katy Ereira | #LonghornPHP Application Auth Handler User
Response Error 401 req. with credentials Create JWT Verify resp. with JWT -
@maccath | Katy Ereira | #LonghornPHP Application Auth Handler User
Action Error 401 Validate JWT req. with JWT -
@maccath | Katy Ereira | #LonghornPHP Part 1 - Header
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 { "alg": "HS256", "typ": "JWT" } -
@maccath | Katy Ereira | #LonghornPHP Part 2 - Payload
(Claims) eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkthdHkiLCJpYXQiOjE1MTYyMzkwMjJ9 { "sub": "1234567890", "name": "Katy", "iat": 1516239022 } -
@maccath | Katy Ereira | #LonghornPHP Part 3 - Signature
DQvkUBA1vHZSIJ46Ue1yXibd0rWoylJFztYrXC50h2A HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), my-super-secret ) -
@maccath | Katy Ereira | #LonghornPHP Q? A. By comparing
the signature to a hash using your shared secret, you can verify that the contents of the JWT are authentic and have not been tampered with. How can I trust that a JWT is authentic? -
@maccath | Katy Ereira | #LonghornPHP Registered Claims JWTs have
a set of registered (useful, interoperable) claims, which include: ◦ aud - audience ◦ nbf - not before ◦ iss - issuer ◦ exp - expiry ◦ iat - issued at ◦ sub - subject -
@maccath | Katy Ereira | #LonghornPHP Custom Claims It is
possible to add your own custom claims to a JWT. Custom claims should be namespaced to avoid collisions. It is recommended to namespace claims using a domain you control. { "sub": "Katy", "https://katy-ereira.co.uk/fav_color": "purple" } -
@maccath | Katy Ereira | #LonghornPHP Other Considerations • Access
tokens are sent in request headers; many servers do not support headers larger than 8kB. Try and keep your JWT and its claims as minimal as possible! • JWTs cannot be invalidated, but they can expire. Set a short expiry time and validate against this to mitigate interception. • Claims within JWTs are only base64 encoded. Don’t encode anything sensitive! -
@maccath | Katy Ereira | #LonghornPHP Remember: Sessions require state
storage; JWTs are stateless and can be verified across multiple services using a shared secret. -
@maccath | Katy Ereira | #LonghornPHP Authorisation Strategies • ABAC
- Attribute Based Access Control • RBAC - Role Based Access Control • ReBAC - Relationship Based Access Control -
@maccath | Katy Ereira | #LonghornPHP Attribute Based Access Control
“My age is over 18 therefore I am permitted to play the lottery” • Very granular and flexible. • Can be used to create complex access conditions. • Can consider of a large number of attributes ◦ nature of actions, time, location, relationships, roles, ages, etc. -
@maccath | Katy Ereira | #LonghornPHP Role Based Access Control
“I am a site administrator therefore I am authorised to delete posts” • Applies set permissions to generalised groups of people • Less complex access conditions when compared with ABAC • May be harder to scale as the number of roles and permissions grow -
@maccath | Katy Ereira | #LonghornPHP Relationship Based Access Control
“I teach this student, so I may view their reports” • Easy to reason about • No need to assign roles or attributes • Harder to scale; when relationship structures evolve, so must the access control -
@maccath | Katy Ereira | #LonghornPHP “ OAuth 2.0 OAuth
2.0 is the industry-standard protocol for authorization. OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices. Reference: https:/ /oauth.net/2/ -
@maccath | Katy Ereira | #LonghornPHP Resource Owner A Resource
Owner is a user or system that owns a protected resource. A Resource Owner can Authorise access to the resources they own. -
@maccath | Katy Ereira | #LonghornPHP Client A Client is
a system that requires access to resources owned by a Resource Owner and protected by a Resource Server. To access resources, a Client must be Authorised by the Resource Owner. -
@maccath | Katy Ereira | #LonghornPHP Auth Server The Auth
Server receives requests from the Client for access to protected resources. It issues access credentials upon successful Authentication of, and Authorisation by the Resource Owner. -
@maccath | Katy Ereira | #LonghornPHP Resource Server The Resource
Server protects the Resource Owner's resources. It receives resource access requests from the Client. The Client sends access credentials along with its request, which the Resource Server verifies. Upon verification, the Resource Server returns the requested resources. -
@maccath | Katy Ereira | #LonghornPHP Auth Server Client Resource
Owner Authorise Authenticate Access Credentials Resource Server Verify Credentials Action 401 (e.g. mobile app) (e.g. an API) (e.g. a user) (e.g. Google accounts) -
@maccath | Katy Ereira | #LonghornPHP Providers? There are many
existing providers of OAuth 2.0 implementations. These include: Facebook, Google, LinkedIn, Instagram, etc. By registering a Client, you can ask a Resource Owner for Authorisation using the provider’s OAuth Server. An authenticated user’s email address may be all your Resource Server needs to validate and fulfil the request. -
@maccath | Katy Ereira | #LonghornPHP Creating an OAuth 2.0
Provider? Of course, you can implement your own OAuth 2.0 provider by following the OAuth 2.0 specification. For now, let’s assume we are integrating with an existing OAuth 2.0 provider such as Google, and that our services have their own database of users with email addresses that belong to Google accounts. -
@maccath | Katy Ereira | #LonghornPHP Grants There are various
ways for a resource owner to grant access to a protected resource via an OAuth provider. Each method for receiving authorisation to access to a protected resource is called a ‘Grant’. -
@maccath | Katy Ereira | #LonghornPHP Authorisation Code Grants A
single-use authorisation code is exchanged for an access token. The authorisation code itself can be securely transferred around a server-side application. Proof Key for Code Exchange (PKCE) is an additional step that makes authorisation code grants more secure for mobile and single-page applications. -
@maccath | Katy Ereira | #LonghornPHP Auth Server Client Resource
Owner Authorise Authenticate Generate Code Resource Server Validate JWT Action 401 Verify Code Generate JWT -
@maccath | Katy Ereira | #LonghornPHP Auth Server Client Resource
Owner Authorise Authenticate Generate Code Resource Server Validate JWT Action 401 Verify Code Generate JWT -
@maccath | Katy Ereira | #LonghornPHP Resource Owner Credentials Grant
For absolutely trusted clients only, the Resource Owner can give its own credentials to the Client (i.e. their username and password), which the Client can then use to authorise with the Auth Server. -
@maccath | Katy Ereira | #LonghornPHP Auth Server Client Resource
Owner Verify Credentials Generate JWT Resource Server Validate JWT Action 401 -
@maccath | Katy Ereira | #LonghornPHP Q? A. You can’t;
which is why the OAuth working group recommends against using or enabling this grant in your OAuth server, and it has been intentionally omitted from the draft OAuth 2.1 spec. Ref: https:/ /datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-19#section-2.4 How can I trust that the client will store the user’s credentials securely? -
@maccath | Katy Ereira | #LonghornPHP Client Credentials Grant A
Client uses its own credentials (e.g. a client ID and secret) to authorise with the Auth Server. This type of grant is used for non-interactive services that do not involve a Resource Owner; e.g. machine-to-machine operations. -
@maccath | Katy Ereira | #LonghornPHP Auth Server Client Verify
Credentials Generate JWT Resource Server Validate JWT Action 401 -
@maccath | Katy Ereira | #LonghornPHP Device Authorisation Grant Can
be used to authorise browserless devices, such as smart TVs. Does not require any interaction with the Auth Server; instead, depends on the Resource Owner authenticating and authorising the device manually. -
@maccath | Katy Ereira | #LonghornPHP Client Auth Server Resource
Owner Verify Credentials Resource Server Validate JWT Action 401 Issue Code Verify Code Request Access Issue JWT Grant Access Granted? display code manual auth -
@maccath | Katy Ereira | #LonghornPHP Refresh Token Grant A
previously authorised Client can refresh its own grant using a securely stored, longer lived refresh token. A Client can maintain access to protected resources without having to ask the Resource Owner for re-authorisation. -
@maccath | Katy Ereira | #LonghornPHP Auth Server Client Verify
Refresh Token Generate JWT Resource Server Validate JWT Action 401 Resource Owner prior auth -
@maccath | Katy Ereira | #LonghornPHP Remember: You can use
multiple grant types depending on the interaction required between your services. -
@maccath | Katy Ereira | #LonghornPHP Other Considerations • Use
HTTPS - always! • Validate redirect URLs, • Short-lived access tokens, long lived refresh tokens • Invalidate longer lived tokens. • Don’t expose private information. -
@maccath | Katy Ereira | #LonghornPHP Time for a recap...
• Authentication vs Authorisation • Authentication Factors • Password Security • Authorisation strategies • Sessions vs. JWTs • OAuth 2.0 Spec -
@maccath | Katy Ereira | #LonghornPHP … later, in Auth
102? • OpenID • Identity Access Management (IAM) • Threat detection • Integrating with Auth0 • … what else did I miss? -
@maccath | Katy Ereira | #LonghornPHP Further Reading & Helpful
Resources • Decode and validate JWTs: https:/ /jwt.io • OAuth simplified: https:/ /oauth.com • Auth0 - auth SaaS: https:/ /auth0.com • OWASP Auth: https:/ /cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html