Auth Bypass on Aws
How Auth Bypass Manifests in AWS
Authentication bypass in AWS environments usually occurs when a service endpoint is reachable without valid credentials or when the authorization logic fails to enforce the intended policy. Common AWS‑specific patterns include:
- Open API Gateway methods – REST or HTTP APIs deployed without an authorizer (Cognito, Lambda, or IAM) allow anyone who knows the URL to invoke the backend Lambda or integration.
- Misconfigured IAM policies – Policies that grant
*:*on a resource or use overly broad condition keys (e.g., missingStringEqualsonaws:SourceArn) let a principal assume a role or call an action they should not be able to. - Public S3 bucket policies – A bucket policy that includes
"Principal": "*"withs3:GetObjectenables unauthenticated reads, which can be leveraged to extract secrets stored as objects. - Lambda function URLs without authentication – When a Lambda is exposed via a function URL and the
AuthTypeis set toNONE, the function runs with the execution role’s permissions regardless of caller identity. - DynamoDB fine‑grained access control misconfigurations – Using
Conditionkeys that reference non‑existent attributes or usingAttributeExistsincorrectly can allow an attacker to read or write items they should not access.
These issues are often introduced during rapid development, infrastructure‑as‑code templating, or when temporary permissions are never tightened after testing.
AWS‑Specific Detection
middleBrick performs unauthenticated, black‑box scanning against the supplied API endpoint. For AWS‑hosted services it probes for the patterns above by:
- Sending requests without any Authorization header or AWS Signature V4 signing and observing whether the endpoint returns a successful response (2xx) instead of 401/403.
- Testing API Gateway routes for missing authorizers by attempting to invoke the integration (e.g., a Lambda) with a random payload and checking for data leakage or state changes.
- Attempting to assume IAM roles via the
sts:AssumeRoleAPI when the role’s trust policy is overly permissive; middleBrick looks for successful role assumption responses that grant temporary credentials. - Probing S3‑backed endpoints (e.g., CloudFront distributions or API Gateway‑S3 integrations) for public object access by requesting known object keys without credentials.
- Checking DynamoDB endpoints (if exposed via API Gateway or AppSync) for fine‑grained policy bypass by issuing
GetItemorScancalls with attribute values that should be blocked by conditions.
When a bypass is detected, middleBrick returns a finding with severity, the affected AWS service, the specific missing control (e.g., "API Gateway method lacks authorizer"), and remediation guidance aligned with the OWASP API Security Top 10 (A1: Broken Object Level Authorization, A2: Broken Authentication).
Example finding (JSON output from the CLI):
{
"finding_id": "aws-apigw-no-authorizer",
"title": "API Gateway method missing authorizer",
"severity": "high",
"service": "Amazon API Gateway",
"description": "The GET /orders endpoint responds 200 without requiring any authentication token or IAM signature.",
"remediation": "Add a Cognito user pool authorizer, Lambda authorizer, or IAM authorization to the method."
}
AWS‑Specific Remediation
Fixing authentication bypass in AWS relies on applying the principle of least privilege using native AWS features. Below are concrete, language‑specific examples that show the vulnerable pattern and the corrected version.
1. Secure an API Gateway REST method with a Cognito authorizer
Vulnerable CloudFormation snippet (no authorizer):
AWSTemplateFormatVersion: '2010-09-09'
Resources:
OrdersApi:
Type: AWS::Serverless::Api
Properties:
StageName: prod
Auth:
DefaultAuthorizer: NONE
AddDefaultAuthorizerToCorsPreflight: false
OrdersGet:
Type: AWS::Serverless::Function
Properties:
Handler: src/orders.getHandler
Events:
GetOrders:
Type: Api
Properties:
Path: /orders
Method: get
RestApiId: !Ref OrdersApi
# No Authorizer defined → vulnerable
Remediated version (adds a Cognito user pool authorizer):
AWSTemplateFormatVersion: '2010-09-09'
Resources:
OrdersApi:
Type: AWS::Serverless::Api
Properties:
StageName: prod
Auth:
DefaultAuthorizer: Cognito
AddDefaultAuthorizerToCorsPreflight: false
OrdersGet:
Type: AWS::Serverless::Function
Properties:
Handler: src/orders.getHandler
Events:
GetOrders:
Type: Api
Properties:
Path: /orders
Method: get
RestApiId: !Ref OrdersApi
Authorizer: CognitoAuthorizer
CognitoAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Name: CognitoOrdersAuthorizer
RestApiId: !Ref OrdersApi
IdentitySource: method.request.header.Authorization
Type: COGNITO_USER_POOLS
ProviderARNs:
- !GetAtt UserPool.Arn
2. Tighten an IAM role trust policy to prevent unintended assumption
Vulnerable trust policy (allows any account to assume the role):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "sts:AssumeRole"
}
]
}
Remediated trust policy (restricts to a specific account and adds an external ID condition):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "unique-random-id-generated-by-consumer"
}
}
}
]
}
3. Enforce private S3 access via bucket policy and VPC endpoint
Vulnerable bucket policy (public read):
{
"Version":"2012-10-17",
"Statement":[{
"Sid":"PublicReadGetObject",
"Effect":"Allow",
"Principal":"*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::my-secret-bucket/*"]
]}
}
Remediated policy (denies any request not coming from the VPC endpoint and requires signed requests):
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"DenyNonVPCAccess",
"Effect":"Deny",
"Principal":"*",
"Action":"s3:*",
"Resource":[
"arn:aws:s3:::my-secret-bucket",
"arn:aws:s3:::my-secret-bucket/*"
],
"Condition":{
"StringNotEquals":{
"aws:SourceVpce":"vpce-0a1b2c3d4e5f6g7h8"
}
}
},
{
"Sid":"AllowVPCRead",
"Effect":"Allow",
"Principal":{
"AWS":"arn:aws:iam::123456789012:role/AppRole"
},
"Action":["s3:GetObject"],
"Resource":"arn:aws:s3:::my-secret-bucket/*"
}
]
}
After applying these controls, middleBrick’s unauthenticated scans will receive 401 or 403 responses, and the finding will no longer appear in subsequent reports.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |