Authentication & Authorization

Authentication: Process of verifying that a user is who they claim to be
Authorization: After authentication, process of verifying wheter a user is allowed to do something
Password-based login vulnerabilities
Missing/Weak Bruteforce Protection
A brute-force attack is when an attacker uses a system of trial and error to guess valid user credentials
Vertical brute-force: Trying many different passwords against a single user account
Horizontal brute-force (Password Spraying): Trying one or a few passwords against many different user accounts
The application lacks controls such as rate limiting, IP throttling or CAPTCHA to prevent automated password guessing
Scenario: An attacker sends a high number of login attempts using different passwords for a known username without being blocked or slowed down
Impact: Successful brute-force attacks can lead to unauthorized access, data breaches, or account takeover
Remediation: Implement rate limiting per IP or account, use CAPTCHA after failed attempts, enforce account lockouts or step-up authentication, and monitor suspicious activity
Password in response
Sensitive password information is included in server responses:
Scenario: After logging in or resetting a password, the system responds with the actual password in plaintext (e.g., in an API or HTML).
Impact: Passwords exposed in transit or logs; high risk of leakage.
Remediation: Never return passwords in responses. Use one-time tokens or status messages only.
Weak Password Requirements
The system allows weak or commonly used passwords without enforcing complexity.
Scenario: Users can create passwords like 123 or password1.
Impact: Easy for attackers to guess or brute-force; increased account compromise risk.
Remediation: Enforce strong password policies (length, complexity, dictionary check) and encourage use of password managers.
Password Stored in Plaintext
Passwords are stored without hashing/encryption.
Scenario: An attacker accesses a database and sees user passwords in readable form.
Impact: All user credentials exposed; leads to mass compromise, especially if reused on other sites.
Remediation: Store passwords using strong one-way hashing algorithms (e.g., bcrypt, Argon2) with salting.
Denial of service via Account Lockout
Account lockout mechanisms, if not carefully designed, can be abused as a vector for denial-of-service attacks.
Scenario: An attacker repeatedly submits wrong passwords for a user (e.g.,
admin@example.com) to trigger the account lockout mechanism.Impact: Legitimate users are locked out of their accounts, causing service disruption or support overhead
Remediation: Use adaptive lockout (e.g., IP-based throttling, CAPTCHA), alert users of suspicious activity, and avoid permanent lockouts. Also, consider progressive delays rather than total blocks
Username Enumeration
The Web application unintentionally reveals whether a username exists in the system. In particular, the server replies with different status codes, error messages or response times if a user already exists or not.
Scenario: An attacker submits different usernames to a login, password reset, or registration form and receives different responses for valid vs. invalid usernames
Impact: Helps attackers identify valid usernames for targeted attacks like brute force, phishing, or social engineering
Remediation: Standardize responses (same message and timing) regardless of whether the username exists.
OTP Bypass (2FA) vulnerabilities
Bypass the OTP verification for the victim authentication, by:
Predictable OTP Generation (Low entropy of the code)
Long or Infinite Validity Period
OTP Reuse
No invalidation after fail (Possible OTP Bruteforce)
Insecure OTP Delivery Channels
No Binding Between OTP and Session (the OTP of another registered user can be used to bypass OTP verification on the victim)
Server Logging OTPs or Exposing codes in frontend code (in plaintext)
Client-Side Validation**
Remediation:
Use TOTP or HMAC-based OTPs (like those in Google Authenticator).
Set short expiry windows (30–60 seconds).
Enable rate limiting and alerting on OTP entry failures.
Use encrypted channels (HTTPS/TLS) for delivery and transmission.
Bind OTP to user session, IP, or device.
Implement multi-factor authentication (MFA) wherever possible.
OAuth 2.0
OAuth is a commonly used authorization framework that enables websites and web applications to request limited access to a user's account on another application.
Definition of a series of interactions between three distinct parties:
Client application: The website or web application that wants to access the user's data.
Resource owner: The user whose data the client application wants to access.
OAuth service provider: The website or application that controls the user's data and access to it. They support OAuth by providing an API for interacting with both an authorization server and a resource server.
OpenID Connect
1. Authorization Request (Client → OAuth Server)
GET /authorization?client_id=12345
&redirect_uri=https%3A%2F%2Fclient-app.com%2Fcallback
&response_type=code
&scope=openid%20profile
&state=ae13d489bd00e3c24 HTTP/1.1
Host: oauth-authorization-server.comRedirect to login page (example):
HTTP/1.1 302 Found
Location: https://oauth-authorization-server.com/login?continue=https%3A%2F%2Foauth-authorization-server.com%2Fconsent2. Login & consent
User submits login credentials (example request):
POST /login HTTP/1.1
Host: oauth-authorization-server.com
Content-Type: application/x-www-form-urlencoded
username=carlos&password=secret123On successful login, the server shows the consent page (scopes to be granted).
User consents (example request):
POST /consent HTTP/1.1
Host: oauth-authorization-server.com
Content-Type: application/x-www-form-urlencoded
consent=yes&scopes=openid%20profile&client_id=12345The server then redirects back to the client’s redirect URI
HTTP/1.1 302 Found
Location: https://client-app.com/callback?code=a1b2c3d4e5f6g7h8&state=ae13d489bd00e3c243. Authorization Code Grant (OAuth Server → Client)
GET /callback?code=a1b2c3d4e5f6g7h8&state=ae13d489bd00e3c24 HTTP/1.1
Host: client-app.comThe client-app.com server extracts the code and state and prepares for token exchange.
🔐 4. Access Token Request (Client Backend → OAuth Server)
POST /token HTTP/1.1
Host: oauth-authorization-server.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic base64(client_id:client_secret)
grant_type=authorization_code&
code=a1b2c3d4e5f6g7h8&
redirect_uri=https%3A%2F%2Fclient-app.com%2FcallbackAlternatively, if no Authorization header:
client_id=12345& client_secret=SECRET& code=a1b2c3d4e5f6g7h8& grant_type=authorization_code& redirect_uri=https%3A%2F%2Fclient-app.com%2Fcallback
🎫 5. Access Token Grant (OAuth Server → Client)
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "z0y9x8w7v6u5",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid profile",
"id_token": "eyJhbGciOiJSUzI1NiIsInR..."
}📡 6. API Call (Client → Resource Server)
GET /userinfo HTTP/1.1
Host: oauth-resource-server.com
Authorization: Bearer z0y9x8w7v6u5The client sends the access token to fetch user profile data.
7. Resource Grant (Resource Server → Client)
HTTP/1.1 200 OK
Content-Type: application/json
{
"username": "carlos",
"email": "carlos@carlos-montoya.net",
"name": "Carlos Montoya",
"sub": "user-12345"
}8. Session management
At the end of the OpenID Connect (OIDC) authentication flow, your application receives two key tokens:
ID Token – used for identifying the user (authentication)
Access Token – used for accessing APIs/resources (authorization)
✅ Which Token Is Used to Access Your App’s Resources?
It depends on how your app is structured:
🔹 1. Traditional Web Application (Server-rendered)
Token used: You typically do not use any token to access internal resources.
Instead, after verifying the ID token, your app:
Creates a server-side session (e.g., a session cookie)
Stores user info (like user ID or email) in the session
All further requests are tracked using a cookie (session ID)
✅ This is stateful authentication ❌ Access token is not used for your app’s own resources
🔹 2. Single Page Application (SPA) + API (Frontend/Backend)
After verifying the ID token, the app:
Stores the access token (and optionally ID token) in memory or secure storage
The frontend sends the access token in the
Authorization: Bearer ...header to the backend
✅ This is stateless authentication ✅ The access token is used to access your own backend API ⚠️ The backend must validate the token (e.g., by checking the signature, expiration, audience)
No OpenID Connect
✅ 1. Authorization Request
The client sends a request to the authorization endpoint to initiate user consent and authorization.
GET /authorization?client_id=12345
&redirect_uri=https%3A%2F%2Fclient-app.com%2Fcallback
&response_type=code
&scope=profile%20email
&state=ae13d489bd00e3c24 HTTP/1.1
Host: oauth-authorization-server.com🔍 Key Parameters:
client_id: Identifies the app.redirect_uri: Where to send the code.response_type=code: Initiates authorization code flow.scope: Noopenidhere — only access scopes.state: Used to prevent CSRF.
🧑💻 2. User Login and Consent
After receiving the authorization request:
Login page shown (redirect):
HTTP/1.1 302 Found
Location: https://oauth-authorization-server.com/login?continue=/consentUser logs in:
POST /login HTTP/1.1
Host: oauth-authorization-server.com
Content-Type: application/x-www-form-urlencoded
username=john.doe@example.com&password=secret123Then consents to data access:
POST /consent HTTP/1.1
Host: oauth-authorization-server.com
Content-Type: application/x-www-form-urlencoded
consent=yes&client_id=12345&scope=profile%20email➡️ If login and consent are successful, the user is redirected back to the client.
🔁 3. Authorization Code Grant (OAuth → Client)
The browser is redirected to the redirect URI with the authorization code:
GET /callback?code=a1b2c3d4e5f6g7h8&state=ae13d489bd00e3c24 HTTP/1.1
Host: client-app.com🔐 4. Access Token Request (Client → OAuth Server)
The client (backend) exchanges the code for an access token:
POST /token HTTP/1.1
Host: oauth-authorization-server.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic base64(client_id:client_secret)
grant_type=authorization_code&
code=a1b2c3d4e5f6g7h8&
redirect_uri=https%3A%2F%2Fclient-app.com%2Fcallback➡️ This is a server-to-server call.
🎫 5. Access Token Grant (OAuth Server → Client)
The server responds with an access token — no ID token is included:
{
"access_token": "z0y9x8w7v6u5",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "profile email"
}➡️ The token grants access to APIs but doesn’t identify the user by itself.
📡 6. API Call (Client → Resource Server)
The client now uses the access token to fetch user data (manually) from a provider-specific endpoint — this replaces the standard /userinfo from OpenID Connect.
Google example (OAuth-only):
GET /oauth2/v1/userinfo HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer z0y9x8w7v6u5Microsoft example (OAuth-only):
GET /v1.0/me HTTP/1.1
Host: graph.microsoft.com
Authorization: Bearer z0y9x8w7v6u5📦 7. Resource Grant (Resource Server → Client)
The resource server validates the token and returns user data (depending on scopes and API):
{
"id": "123456789",
"name": "John Doe",
"email": "john.doe@example.com"
}➡️ Your app uses this to create or identify a user session.
Would you like provider-specific examples (Google vs Microsoft vs Facebook) for the user info request step?
Web
Once the Application has the user's info (e.g., email):
The Web Server needs to check if the user exists in the DB
If yes, the user will be logged in
If not, an account will be created and then the usser will be logged in
A session will be created and the token/cookied will be returned to the client
Key Differences (OpenID Connect vs NO OpenID Connect)
Identity via id_token
✅ Yes
❌ No
Uses /userinfo endpoint
✅ Standardized
❌ Provider's API need to be used
Supports login & SSO
✅ Yes
⚠️ Only if implemented by Web App
Access to profile/email
✅ Standard scopes
⚠️ Requires API access
Last updated