Insights

Authentication Weaknesses in APIs: Is the Back End as Secure as the Login Page?

Weak API authentication can allow attackers to bypass login controls, MFA and session protections. Manual testing helps uncover these hidden weaknesses.

Penetration tester demonstrating how an insecure API could bypass controls on a protected login page.

A login page can look reassuringly secure. It might require a strong password, display a CAPTCHA after several failed attempts and prompt the user for a multi-factor authentication code.

But the login page is only the visible part of the authentication process.

Behind it, the application may rely on one or more application programming interfaces, or APIs, to check credentials, verify MFA codes and issue the tokens that keep users signed in. If those APIs enforce weaker controls than the interface, an attacker may be able to avoid the protections that legitimate users see on screen.

That is why a web application penetration test should assess the API directly, rather than testing the application solely through a browser.

The login page is only the front door

Modern web and mobile applications commonly use APIs to perform authentication and retrieve data. When a user enters their details, the application might send a request such as:

POST /api/auth/login

If the credentials are accepted, the API may return a session cookie, an access token, a refresh token, a JSON Web Token or a temporary token used to complete MFA.

The interface may limit repeated attempts or present a CAPTCHA, but those protections matter only if the server applies them to the underlying requests. An attacker does not have to click the login button. They can attempt to communicate with the API directly.

The important question is therefore: what happens when somebody ignores the interface and sends their own requests to the back end?

How API authentication works

A typical API authentication process has several stages:

  1. The client sends the user’s credentials to the API.
  2. The API validates those credentials.
  3. The user completes any additional checks, such as MFA.
  4. The API issues a session or token.
  5. The client includes that credential with later requests.
  6. The API uses it to identify the user and decide whether the requested action is permitted.

Weaknesses can arise at every stage. The API might reveal whether an account exists, permit too many password attempts, issue a token before MFA has been completed or continue accepting a stolen token after the user has logged out.

It is also important to distinguish authentication from authorisation. Authentication establishes who the user is. Authorisation determines what that user is allowed to see or do. Both are essential, although this article focuses on how an API establishes and maintains a user’s identity.

Finding every route into an account

Before authentication can be assessed properly, the tester needs to understand the complete authentication surface.

Relevant endpoints can be discovered by examining browser and mobile application traffic, JavaScript files, API documentation, OpenAPI definitions, GraphQL operations and error messages. Testers may also enumerate endpoints and look for historical or legacy API versions that remain accessible.

The resulting map may include far more than a single login endpoint. It could cover:

  • Login and logout
  • MFA verification
  • Token refresh
  • Password reset and account recovery
  • Account activation and email verification
  • Device registration
  • Single sign-on
  • Active-session management

This matters because different routes do not always enforce the same controls. The main website may require MFA, for example, while an old mobile endpoint still accepts a username and password alone.

Can the API reveal valid usernames?

Many applications deliberately show a generic message such as “the username or password was incorrect” after a failed login. The API behind that screen may be less discreet.

It might return visibly different responses:

{"error":"user_not_found"}

and:

{"error":"incorrect_password"}

Even when the wording is identical, differences in HTTP status codes, response lengths, error identifiers or response times may reveal whether an account exists. Password-reset, registration and MFA endpoints can disclose the same information through their responses or behaviour.

Username enumeration does not compromise an account by itself, but it gives an attacker a reliable list of targets. That information can support password spraying, credential stuffing, targeted phishing and other attempts at account takeover.

Missing or inconsistent rate limiting

Rate limiting controls how frequently a client can perform an action. It is particularly important for login, MFA and account-recovery functions, where unrestricted attempts can turn guessing into a practical attack.

A web page might slow down repeated attempts while the API continues accepting requests at full speed. Controls may also be present on the main login endpoint but absent from password reset, telephone or email verification, token refresh, mobile APIs, older API versions or GraphQL authentication mutations.

The way limits are calculated matters too. A restriction based only on source IP address may be bypassed by distributing attempts across different addresses. A limit based only on username may allow an attacker to target many users. Session identifiers, device identifiers and client-supplied headers can sometimes be changed or reset.

Effective protection normally considers several signals, such as the account, source, device, request pattern and overall activity across the service. Monitoring and alerting are also needed because a sufficiently distributed attack may remain below any single threshold.

Password spraying and credential stuffing

Password spraying tests a small number of likely passwords across many accounts. Instead of repeatedly attacking one user and triggering a lockout, the attacker spreads attempts across the user population.

An API can make this easier when it offers predictable requests, clear success and failure responses, weak rate limiting, no meaningful anti-automation control and no detection across multiple accounts. If MFA is not enforced, one reused or predictable password may be enough to gain access.

Credential stuffing is similar, but uses username and password combinations exposed in breaches of other services. It exploits the fact that people sometimes reuse passwords.

Defences include MFA, screening new passwords against known breached-password data, effective rate limiting, behavioural detection and monitoring for distributed authentication attempts. During an authorised penetration test, password-based testing should use agreed accounts and conservative limits to avoid locking out or disrupting genuine users.

Is MFA really enforced by the API?

After a user submits the correct password, an application may create a partial session or issue a temporary token so that they can enter an MFA code. That credential should permit only the actions needed to complete authentication.

A tester will investigate whether it can instead be used to retrieve account information, access protected endpoints, download files, change settings or obtain a fully authenticated token. They may also check whether an older endpoint overlooks the user’s incomplete authentication state.

The server must distinguish clearly between three states:

  • The password has been verified
  • MFA is still required
  • Authentication has been completed

That state must be recorded securely and checked by every sensitive endpoint. Hiding protected pages in the browser until MFA is complete is not sufficient. If the API accepts the temporary credential, an attacker can call it without using the intended interface.

MFA endpoints need protection too

MFA verification is itself an authentication endpoint and should be treated accordingly.

Testing may examine whether verification attempts are rate-limited, whether codes can be reused and whether they remain valid for an excessive period. A new code should normally invalidate the previous one, and each code should be tied to the correct account, authentication attempt and session.

Other important questions include whether multiple codes can be submitted concurrently, whether alternative MFA methods offer weaker protection and whether successful verification causes the session or token to be rotated. If the same pre-MFA token remains in use, weaknesses in session handling may make it easier to reuse or steal.

Restricting attempts in the visible interface achieves little if the API accepts unlimited submissions.

Tokens should not be issued too early

A fully privileged token should be issued only after every required authentication step has been completed.

Potential problems include issuing a full access token immediately after password verification, trusting an MFA claim that the client can influence or allowing a temporary token to access protected endpoints. In some cases, a login response may expose both partial and complete credentials, with front-end code being relied upon to select the correct one.

The client should never be responsible for deciding whether the user has completed authentication. Every API handling sensitive data or actions must validate the authentication state on the server.

Access tokens and session security

An access token represents an authenticated user. Anyone who obtains a valid token may be able to act as that person without knowing their password.

A penetration test may consider whether tokens are sufficiently random and unpredictable, how long they remain valid and whether their scope is appropriate. It should also examine how tokens are stored and transmitted, whether they appear in URLs or logs and whether each API service validates them consistently.

The session lifecycle is just as important. Does the token stop working after logout? What happens after a password change, account suspension or manual session revocation? Can the same token be used by an unintended application or against another service?

Short-lived access tokens can reduce the window in which a stolen token is useful, but they are effective only when the associated refresh tokens are also protected.

JSON Web Tokens are not inherently insecure

Many APIs use JSON Web Tokens, commonly known as JWTs. A JWT can carry claims about the user, token issuer, intended audience, privileges and expiry time.

A tester may assess whether the API verifies the token’s signature correctly, accepts only appropriate signing algorithms and selects the correct verification key. They may also review secret strength, issuer and audience validation, expiry handling, replay risks, claim processing and key rotation.

JWTs are not inherently insecure. Problems arise when they are implemented or validated incorrectly.

It is also worth remembering that JWT contents are normally encoded, not encrypted. A person who obtains the token may be able to read its claims even if they cannot alter them. Sensitive information should not be placed in a token merely because the token is signed.

Refresh tokens can provide persistent access

Refresh tokens allow an application to request new access tokens without asking the user to log in again. Because they may remain valid for much longer than access tokens, they are especially valuable to an attacker.

Testing should establish whether refresh tokens are unpredictable, stored securely and tied to the correct client. Stronger implementations rotate a refresh token after use and detect reuse of an older token, which can indicate theft.

Refresh tokens should also expire after a reasonable period and be revoked following logout, password changes, MFA changes or other security-sensitive events. Where appropriate, users should be able to view and terminate their active sessions.

Without these controls, a stolen refresh token may provide continuing access long after the original access token has expired.

Does logout actually end the session?

A logout button can create the impression that a session has ended when the application has merely deleted the token from the browser. If a copied token remains valid at the API, an attacker who already possesses it can continue using the account.

A tester may check whether tokens remain usable after logout, password changes, MFA replacement, account recovery, account suspension, role removal, user deletion and manual session revocation.

Stateless token designs can make immediate revocation more complicated, but the technical design does not remove the business need to terminate a compromised session. Applications need an appropriate revocation strategy for high-risk events.

Legacy APIs can undermine current controls

Applications often retain old endpoints to support previous versions of a website, mobile app or integration. These might include routes such as:

/api/v1/login
/api/v2/login
/mobile/authenticate
/legacy/session

An obsolete endpoint might accept password-only authentication, omit MFA, use a weaker token format, lack effective rate limiting or reveal more detailed errors. The risk becomes particularly serious if a token issued by the old service is trusted by the current API.

Removing a login button from the current interface does not disable the endpoint behind it. Testers therefore need to establish which historical routes remain reachable and how credentials issued by one service are treated by others.

Mobile APIs may apply different rules

Mobile applications sometimes use different endpoints, client identifiers or headers from the main website. They may also issue longer-lived tokens or support older authentication protocols.

A tester may compare whether the mobile API applies the same MFA policy, rate limits and account-recovery controls. They may also look for embedded API credentials, client-controlled device identifiers and supposed device or certificate checks that do not provide the protection expected of them.

Attackers are not obliged to use the official mobile application. They can observe its traffic and reproduce requests using their own tools. Any secret distributed inside an application should therefore be assumed recoverable, and client-side restrictions should not be treated as a security boundary.

Authentication through GraphQL

GraphQL applications commonly expose many operations through a single HTTP endpoint. This can make request-based controls misleading.

For example, a single request may contain batched operations or multiple aliases, potentially allowing numerous login attempts while appearing to be one HTTP request. Effective rate limiting must consider the number and cost of the operations inside the request, not simply the number of requests reaching the endpoint.

Testing may also uncover protected fields accessible before full authentication, inconsistent checks between resolvers, detailed errors that reveal valid users or introspection data that exposes authentication operations.

Single sign-on and federated identity

Where an API accepts tokens from Microsoft Entra ID or another identity provider, it must do more than confirm that the token looks genuine.

The API should validate the signature, expected issuer, intended audience, expiry and validity times, required scopes, user identity, tenant identity and any necessary authentication-strength or MFA claims.

A valid token issued for one application, environment or tenant should not automatically be accepted by another. Local API login routes should also be reviewed to make sure they cannot bypass the organisation’s single sign-on and MFA policies.

API keys are not proof of a user’s identity

API keys are often intended to identify a calling application, integration or customer system. They are not necessarily suitable for authenticating an individual user.

Problems arise when keys are embedded in browser code or mobile applications, committed to public repositories, disclosed in errors, placed in URLs, shared between customers, granted excessive permissions or never rotated.

A publicly distributed application cannot reliably keep a static embedded secret. An API should not treat possession of a widely exposed application key as evidence that a request came from an authenticated user.

Tokens can leak beyond the login process

Authentication security extends across the complete application architecture. A well-designed login flow can still be undermined if its tokens are exposed elsewhere.

Potential routes include insecure cross-origin resource sharing, unsafe browser storage, third-party scripts, URLs and referrer headers, application logs, analytics platforms, error-monitoring services, redirects and cached responses.

The organisation therefore needs to understand where tokens travel, which systems can see them and how those systems protect the data they collect.

How a penetration tester assesses API authentication

A structured assessment normally combines several strands of work.

Map the authentication surface

The tester identifies web, mobile, legacy, administrative and single sign-on routes, including recovery and device-registration functions.

Compare interface and API controls

They establish whether protections visible in the browser are actually enforced by the server and whether equivalent controls apply across every client and API version.

Analyse authentication states

Requests, sessions and tokens are compared before login, after password acceptance, after MFA and following changes to the user’s privileges or security settings.

Assess protection against automated attacks

Using agreed accounts and safe limits, the tester examines username enumeration, rate limiting, password-spraying protections and MFA attempt controls.

Review token security

Access tokens, refresh tokens and JWTs are assessed for appropriate scope, validation, expiry, rotation, storage and revocation.

Examine alternative routes

Password reset, account activation, device registration, mobile services and older API versions are checked for weaker authentication paths.

Test the complete session lifecycle

The tester verifies what happens after logout, password and MFA changes, privilege changes, account suspension and manual session termination.

Validate every service

Where several APIs accept the same credentials, each service is checked for consistent authentication requirements and token-validation rules.

Why an automated scanner may miss the problem

Automated scanners can identify some obvious token issues and configuration weaknesses. They are less capable of understanding how an application’s authentication process is intended to work.

Meaningful testing requires knowledge of the expected login sequence, the difference between partial and complete authentication, the roles assigned to test accounts, the relationship between access and refresh tokens and the purpose of mobile, legacy and recovery endpoints.

A scanner may observe that an endpoint returned data. A manual tester determines whether that endpoint should have accepted the particular session or token presented to it.

The greatest risk may come from a chain of weaknesses

Authentication flaws are especially dangerous when they can be combined. Consider the following example:

  1. A password-reset endpoint reveals valid usernames.
  2. Login rate limiting applies only to individual source IP addresses.
  3. A distributed password-spraying attack identifies a valid password.
  4. A legacy API endpoint accepts that password without requiring MFA.
  5. The resulting refresh token remains valid even after the password is changed.

Each weakness might receive a different risk rating in isolation. Together, they provide a practical and persistent route to account compromise.

This is why a good penetration test looks beyond isolated observations and considers the attack paths that those weaknesses could create.

What could weak API authentication mean for the business?

If API authentication can be bypassed or abused, an attacker may be able to:

  • Take over customer or employee accounts
  • Access personal, financial or commercially sensitive information
  • Impersonate legitimate users
  • Perform fraudulent transactions
  • Compromise administrative accounts
  • Maintain persistent access
  • Automate attacks against large numbers of users
  • Bypass security controls presented to customers

The consequences could include financial loss, a reportable data breach, regulatory exposure, service disruption and lasting damage to customer confidence.

How to strengthen API authentication

Organisations can reduce these risks by:

  • Enforcing authentication and MFA on the server
  • Applying equivalent controls across every API, client and supported version
  • Returning generic failure responses that do not reveal whether an account exists
  • Implementing multi-layered rate limiting and anti-automation controls
  • Monitoring for password spraying, credential stuffing and distributed attacks
  • Strictly limiting what partial-authentication tokens can do
  • Issuing fully privileged tokens only after every authentication step is complete
  • Using short-lived, appropriately scoped access tokens
  • Storing, rotating and revoking refresh tokens securely
  • Validating JWT signatures, algorithms, issuers, audiences, claims and expiry
  • Revoking sessions after security-sensitive account changes
  • Removing obsolete authentication endpoints and protocols
  • Avoiding reliance on client-side restrictions or embedded secrets
  • Applying strong protection to recovery, verification and device-registration APIs
  • Keeping tokens out of URLs, logs and unnecessary third-party services
  • Logging suspicious authentication activity and generating useful alerts
  • Conducting manual security testing after significant authentication changes

Secure the API, not just the screen

A polished login page may provide a false sense of security if the API behind it accepts requests through weaker routes.

A meaningful assessment should establish whether users can be enumerated, whether automated attacks are practical, whether MFA is enforced by every relevant endpoint and whether tokens are issued, validated and revoked securely. It should compare the web, mobile, legacy, administrative and federated authentication routes, then consider whether separate weaknesses can be combined into a realistic attack.

The real question is not whether the login page looks secure. It is whether the API will accept something that the interface would reject.

Is your application’s API enforcing the same security controls as its login page? Plainsight Security assesses authentication endpoints, MFA workflows, access tokens, refresh tokens and session handling as part of a manual web application penetration test. Contact us to discuss your requirements.

Portrait of Plainsight Security's lead tester

Written by

Mark Tomlinson

Our lead penetration tester, Mark Tomlinson, holds The Cyber Scheme Team Leader qualification in infrastructure penetration testing, an advanced certification recognised by the National Cyber Security Centre (NCSC) and used by professionals testing government systems and UK critical national infrastructure. Mark is also registered with the UK Cyber Security Council as a Principal Cyber Security Professional (PriCSP) specialising in Security Testing and holds an MSc in Computer Science with Cyber Security.

More about how we work
Talk to a tester

Put this into practice.

Cyber Essentials, Cyber Essentials Plus, and penetration testing — fixed-price, plain English, and built to stay out of your way.

← All insights