Back

SAS-2: Broken Authentication - Overview

What is Broken Authentication in Serverless?

Broken Authentication in a serverless application is the failure to consistently and correctly verify who (or what) is invoking a function, across every way that function can be reached. It is not a single missing login form—it is the gap that opens when a highly distributed, stateless collection of functions is protected in some places and left open in others.

Traditional applications have a small number of entry points, usually funnelled through one web server and one authentication layer. Serverless flips that model: an application is a fleet of small, independently deployable functions, and each function can be triggered by many different event sources—an API Gateway request, a public Function URL, an S3 object-created event, an SNS or SQS message, an EventBridge rule, a DynamoDB stream, a scheduled timer, or a direct SDK Invoke call. Authentication that is enforced at the front-door API Gateway does nothing for a function reached through any of the other doors.

Core Concept

Secure Authentication (serverless):
  Every entry point   -> authenticated, no exceptions
  Identity            -> one central provider (e.g. Cognito) for user auth
  Tokens              -> signature + expiry + audience + issuer validated
  Event triggers      -> treated as untrusted; caller/context verified
  Service-to-service  -> signed IAM/SigV4, least-privilege roles
  Function URLs       -> AWS_IAM auth or an authorizer, never open by default

Broken Authentication:
  Some entry points   -> API Gateway authorized, other triggers wide open
  Identity            -> each function rolls its own ad-hoc check
  Tokens              -> decoded but not verified (no signature/expiry check)
  Event triggers      -> assumed "internal", so trusted blindly
  Service-to-service  -> shared static secret, or no auth at all
  Function URLs       -> AuthType NONE, reachable by anyone who finds the URL

Why It's Critical for Serverless

Serverless architecture concentrates several conditions that make authentication uniquely hard to get right:

Why Does This Matter?

Business Impact

Technical Impact

Technical Context

Common Broken-Authentication Scenarios in Serverless

1. Public Function URL with No Auth

# serverless.yml - a Lambda exposed directly to the internet
functions:
  adminReport:
    handler: handler.adminReport
    url:
      authorizer: none        # AuthType: NONE - anyone with the URL invokes it

The function is now a public HTTPS endpoint. It never passes through API Gateway, so any authorizer configured there is irrelevant.

2. Assuming Event-Triggered Functions Are "Internal"

# A function triggered by an S3 upload assumes the event is trusted
def handler(event, context):
    key = event['Records'][0]['s3']['object']['key']
    # Acts on attacker-influenced key/content with no further checks
    process_and_publish(key)

Risk: The uploader may be untrusted (public bucket, a partner, a compromised path). The event source is not proof of a trusted, authenticated actor.

3. Tokens Decoded but Not Verified

// Broken JWT handling inside a Lambda
const parts = token.split('.');
const claims = JSON.parse(Buffer.from(parts[1], 'base64'));  // decode only
if (claims.role === 'admin') { /* trusted! */ }              // no signature check

Risk: Anyone can base64-encode {"role":"admin"}. Without verifying the signature, expiry, audience, and issuer, the claims are attacker-controlled.

4. Inconsistent Auth Across the Fleet

getProfile   -> API Gateway + Cognito authorizer   (protected)
updateProfile-> API Gateway + Cognito authorizer   (protected)
exportData   -> Function URL, AuthType NONE         (WIDE OPEN)
internalSync -> direct Invoke, no caller check       (WIDE OPEN)

Risk: Attackers enumerate the fleet and target the weakest function, not the front door.

5. Relying on the Obscurity of an ARN or URL

https://abc123def456.lambda-url.us-east-1.on.aws/

Risk: A random-looking URL or ARN is not a secret. URLs leak through logs, referrer headers, client code, and history; obscurity is not authentication.

Entry Points Where Authentication Is Missed

Entry Point / TriggerTypical Broken-Auth MistakeConsequence
API GatewayAuthorizer on some routes, forgotten on othersUnauthenticated access to specific operations
Lambda Function URLAuthType: NONE left in placePublic, bypasses gateway entirely
S3 / SNS / SQS / EventBridgeEvent treated as inherently trustedActs on attacker-influenced input
Direct SDK InvokeNo verification of the calling principalAny principal with invoke rights acts unchecked
Custom token logicDecode without verifying signature/expiryIdentity forgery, privilege escalation
Scheduled / stream triggersAssumed unreachable by outsidersPrivileged logic runs on unverified data

Real-World Impact

The classes below describe recurring, well-documented patterns in serverless deployments. They are incident classes, not specific named breaches or CVEs.

Case Class 1: Public Function URLs Reachable Without Auth

Broken Authentication:

Impact:

Root Cause: An entry point that skips the central authentication layer, shipped without its own auth. The fix is to require AWS_IAM or an authorizer on the URL, or to remove the URL entirely.

Case Class 2: Trusting "Internal" Event Triggers

Broken Authentication:

Impact:

Root Cause: Conflating "the trigger is an AWS service" with "the actor is authenticated and authorized." The event source is transport, not identity.

Case Class 3: Broken or Absent Token Validation

Broken Authentication:

Impact:

Root Cause: Treating a token as trustworthy because it is well-formed rather than because it is cryptographically valid and current. The fix is complete verification against the identity provider's keys plus short lifetimes.

Prevalence and Characteristics

Broken Authentication sits at the top of the OWASP Serverless concerns precisely because the architecture multiplies the number of places authentication must be enforced. Every additional function and every additional trigger type is another opportunity to get it wrong.

Rather than cite precise counts (which vary by source), the defensible picture is:

Note: exact percentages differ between reports and years. The durable takeaway is that in serverless the hard part is not having authentication—it is enforcing it consistently at every one of many entry points.

Common Misunderstandings

Myth 1: "The API Gateway authorizer protects everything"

Reality: It protects only requests that actually pass through that gateway. Function URLs, direct invokes, and event-source triggers reach the function without ever touching the gateway or its authorizer.

Myth 2: "Event-triggered functions are internal, so they don't need auth"

Reality: S3, SNS, SQS, and EventBridge sources can be influenced by untrusted input. "Triggered by an AWS service" is not the same as "invoked by an authenticated, authorized actor."

Myth 3: "A random Function URL / ARN is secret enough"

Reality: URLs and ARNs leak through client code, logs, referrers, and browser history. Obscurity delays discovery; it never authenticates a caller.

Myth 4: "If the JWT decodes, the user is who they claim"

Reality: Anyone can craft a well-formed JWT. Only verifying the signature, expiry, audience, and issuer against the identity provider's keys establishes trust.

Myth 5: "Each function can do its own quick auth check"

Reality: Ad-hoc per-function checks drift out of sync and leave gaps. A central identity provider and a consistent, reused authorizer are far harder to get wrong across a large fleet.

Myth 6: "Internal service-to-service calls don't need credentials"

Reality: Any principal that can reach an invoke path is a potential caller. Service-to-service calls must be signed (IAM/SigV4) and scoped with least-privilege roles, not left open.

How Broken Authentication Differs from Related Issues

AspectBroken Authentication (SAS-2)Broken Authorization (access control)Security Misconfiguration
Core questionIs the caller who they claim to be?Is this caller allowed to do this?Is the platform hardened correctly?
Typical failureNo/weak identity check at an entry pointIdentity known but limits not enforcedInsecure defaults/settings
Typical fixAuthenticate every entry point, verify tokensEnforce per-resource permission checksHarden and disable defaults
DetectionEnumerate triggers, test each unauthenticatedTest cross-user/cross-role accessConfig/IaC scan

Key Takeaways

  1. Authentication must hold at every entry point—the gateway is one door of many; Function URLs, direct invokes, and event triggers are the others.
  2. "Internal" is not "authenticated"—event sources carry untrusted input and prove nothing about the actor.
  3. Centralise identity—one provider and a consistently applied authorizer beat per-function improvisation.
  4. Verify tokens fully—signature, expiry, audience, and issuer, every time; decoding is not verifying.
  5. Assume each function is directly reachable—and authenticate it as if it is, backed by least-privilege roles so an unauthenticated call can do little.

How to Identify if You're Vulnerable

Ask these questions about your serverless application:

If you answered "no" or "not sure" to several of these, you likely have an unauthenticated path into privileged logic today.

Next Steps