Bola Idor on Aws
How BOLA/IdOR Manifests in AWS
Broken Object Level Authorization (BOLA), also known as Insecure Direct Object References (IDOR), occurs when an application fails to properly validate whether a user has permission to access specific objects. In AWS environments, this vulnerability manifests through several unique patterns specific to AWS services and their access control models.
The most common AWS-specific BOLA pattern involves S3 bucket access. Consider this vulnerable code:
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
app.get('/files/:key', async (req, res) => {
const { key } = req.params;
const params = { Bucket: 'my-bucket', Key: key };
const data = await s3.getObject(params).promise();
res.send(data.Body.toString());
});This endpoint allows any authenticated user to access any file in the S3 bucket by simply changing the file key in the URL. The application trusts the user-provided key without verifying ownership or permissions.
Another AWS-specific pattern appears in DynamoDB operations. Here's a vulnerable example:
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
app.get('/users/:id/profile', async (req, res) => {
const { id } = req.params;
const params = {
TableName: 'UserProfiles',
Key: { userId: id }
};
const data = await dynamodb.get(params).promise();
res.json(data.Item);
});This code retrieves any user's profile by ID without checking if the requester owns that profile. An attacker can simply iterate through user IDs to access all profiles.
AWS Lambda functions present unique BOLA opportunities when they process events without proper validation. Consider this vulnerable Lambda:
exports.handler = async (event) => {
const { userId, documentId } = event.queryStringParameters;
const s3 = new AWS.S3();
const params = { Bucket: 'company-documents', Key: `${userId}/${documentId}` };
const data = await s3.getObject(params).promise();
return { statusCode: 200, body: data.Body.toString() };
};If the Lambda trusts the userId parameter from the event, an attacker can access any user's documents by modifying the userId parameter.
AWS API Gateway can also introduce BOLA vulnerabilities through improper resource policies. Here's an insecure configuration:
Resources:
UserResource:
Type: AWS::ApiGateway::Resource
Properties:
PathPart: '{proxy+}'
ParentId: !Ref UsersResource
RestApiId: !Ref ApiGatewayApiThis wildcard resource path allows unrestricted access to any sub-resource without validation.
AWS-Specific Detection
Detecting BOLA vulnerabilities in AWS requires both manual code review and automated scanning. middleBrick's AWS-specific detection capabilities include:
Runtime Parameter Analysis: middleBrick analyzes how AWS SDK parameters are constructed and whether user input is properly validated before being passed to AWS services. For S3 operations, it checks if the Key parameter is derived from user input without validation.
Cross-Reference with IAM Policies: middleBrick compares the code's access patterns against the principle of least privilege. If your IAM role allows broader access than the code requires, this indicates potential BOLA exposure.
API Gateway Resource Analysis: middleBrick examines API Gateway configurations for wildcard paths and missing authorization checks at the resource level.
Lambda Event Validation: The scanner checks if Lambda functions validate event parameters before using them in AWS service calls.
Here's how you'd scan an AWS-hosted API with middleBrick:
npm install -g middlebrick
middlebrick scan https://api.example.com --output jsonThe scanner will identify specific BOLA patterns in your AWS implementation, such as:
- Direct S3 key manipulation without ownership verification
- DynamoDB queries using user-controlled partition keys
- Lambda functions processing untrusted event parameters
- API Gateway resources missing authorization checks
For AWS developers, middleBrick provides additional value by understanding AWS-specific authentication mechanisms. It can detect when Cognito user pools or IAM roles are improperly configured to allow broader access than intended.
AWS-Specific Remediation
Remediating BOLA vulnerabilities in AWS environments requires a defense-in-depth approach using AWS's native security features. Here are AWS-specific fixes for the vulnerable patterns shown earlier:
S3 Bucket Access Control: Instead of allowing direct object access, implement user-specific prefixes and validate ownership:
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
app.get('/files/:key', async (req, res) => {
const { key } = req.params;
const userId = req.user.id; // from authentication middleware
// Validate that the file belongs to the user
const params = { Bucket: 'my-bucket', Key: `${userId}/${key}` };
try {
const data = await s3.getObject(params).promise();
res.send(data.Body.toString());
} catch (error) {
if (error.code === 'NoSuchKey') {
res.status(404).send('File not found');
} else {
res.status(500).send('Internal server error');
}
}
});DynamoDB Authorization: Use IAM policies with conditions to restrict access:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["dynamodb:GetItem"],
"Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/UserProfiles",
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": ["${cognito-identity.amazonaws.com:sub}"]
}
}
}
]
}Lambda Security: Validate event parameters and use IAM roles with least privilege:
exports.handler = async (event) => {
const userId = event.requestContext.authorizer.claims.sub;
const documentId = event.queryStringParameters?.documentId;
// Validate that the user owns this document
const s3 = new AWS.S3();
const params = { Bucket: 'company-documents', Key: `${userId}/${documentId}` };
try {
const data = await s3.getObject(params).promise();
return { statusCode: 200, body: data.Body.toString() };
} catch (error) {
return { statusCode: 404, body: 'Document not found' };
}
};API Gateway Authorization: Implement resource-level authorization using Lambda authorizers:
Authorizers:
CognitoUserPoolAuthorizer:
Type: COGNITO_USER_POOLS
ProviderARNs:
- arn:aws:cognito-idp:us-east-1:123456789012:userpool/us-east-1_xxxxxxxxxVPC Isolation: For sensitive data, consider placing S3 buckets and DynamoDB tables in VPC endpoints to prevent direct internet access:
Resources:
PrivateS3Bucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: Private
VpcConfiguration:
VpcId: !Ref VPC
VpcEndpointId: !Ref VPCEndpointCloudTrail Monitoring: Implement monitoring for suspicious access patterns:
Resources:
CloudTrailBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref CloudTrailBucket
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: { Service: cloudtrail.amazonaws.com }
Action: s3:GetBucketAcl
Resource: !GetAtt CloudTrailBucket.Arn
- Effect: Allow
Principal: { Service: cloudtrail.amazonaws.com }
Action: s3:PutObject
Resource: !Sub 'arn:aws:s3:::${CloudTrailBucket}/AWSLogs/${AWS::AccountId}/*'Related CWEs: bolaAuthorization
| CWE ID | Name | Severity |
|---|---|---|
| CWE-250 | Execution with Unnecessary Privileges | HIGH |
| CWE-639 | Insecure Direct Object Reference | CRITICAL |
| CWE-732 | Incorrect Permission Assignment | HIGH |