Cloud4 Min Read

OWASP Top 10 for Cloud Applications

Gorav Singal

April 04, 2026

TL;DR

The OWASP Top 10 still applies in the cloud — but the attack surface changes. Broken access control means misconfigured IAM, injection means Lambda event injection, and SSRF is the #1 cloud-specific risk. Learn the cloud twist on each vulnerability.

OWASP Top 10 for Cloud Applications

The OWASP Top 10 was written for traditional web applications. But in the cloud, the attack surface shifts. SQL injection becomes Lambda event injection. Broken access control becomes misconfigured IAM. And SSRF — barely a footnote in traditional web security — becomes the most dangerous cloud-specific attack vector.

This article maps each OWASP category to its cloud-native equivalent.

OWASP Top 10 in the Cloud Era

OWASP Cloud Attack Surface Mapping

A01: Broken Access Control

Traditional: User accesses another user’s data by changing an ID in the URL. Cloud twist: IAM misconfigurations, overly permissive S3 bucket policies, cross-account access without proper controls.

// ❌ S3 bucket policy — allows anyone to read
{
  "Effect": "Allow",
  "Principal": "*",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::customer-data/*"
}

// ✅ Restricted to specific role
{
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::123456789:role/ApiServer"
  },
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::customer-data/*"
}

Cloud defenses: IAM least privilege, S3 Block Public Access, resource-based policies with explicit principals.

A02: Cryptographic Failures

Traditional: Transmitting sensitive data over HTTP, weak hashing. Cloud twist: Unencrypted S3 buckets, unencrypted RDS instances, KMS key mismanagement.

# Check all S3 buckets for encryption
aws s3api list-buckets --query 'Buckets[].Name' --output text | \
  xargs -I {} sh -c 'echo -n "{}: "; aws s3api get-bucket-encryption --bucket {} 2>/dev/null || echo "NOT ENCRYPTED"'

Cloud defenses: KMS encryption for all data at rest, TLS 1.2+ for all data in transit, SCPs enforcing encryption.

A03: Injection

Traditional: SQL injection via form inputs. Cloud twist: Lambda event injection — untrusted data arrives from SQS, S3 events, API Gateway, and other AWS services.

# ❌ Lambda event injection — S3 key used in shell command
import subprocess

def handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']
    # Attacker uploads file named: "; rm -rf / #"
    subprocess.run(f"process-file {bucket}/{key}", shell=True)  # INJECTION!

# ✅ Safe — use parameterized approach
def handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']
    subprocess.run(["process-file", f"{bucket}/{key}"], shell=False)

Cloud defenses: Input validation on all event sources, parameterized commands, WAF on API Gateway.

A04: Insecure Design

Cloud twist: Architectures that don’t consider security boundaries — flat VPCs, shared service accounts, no network segmentation between microservices.

Cloud defenses: Threat modeling with STRIDE, network policies in Kubernetes, separate AWS accounts for prod/staging/dev.

A05: Security Misconfiguration

This is the #1 cloud vulnerability. More breaches happen from misconfiguration than from exploits.

# Common misconfigurations to check
# 1. Public security groups
aws ec2 describe-security-groups \
  --filters "Name=ip-permission.cidr,Values=0.0.0.0/0" \
  --query 'SecurityGroups[].{ID:GroupId,Name:GroupName}'

# 2. IMDSv1 enabled (allows SSRF credential theft)
aws ec2 describe-instances \
  --query 'Reservations[].Instances[?MetadataOptions.HttpTokens!=`required`].{ID:InstanceId,State:State.Name}'

# 3. Public RDS instances
aws rds describe-db-instances \
  --query 'DBInstances[?PubliclyAccessible==`true`].{ID:DBInstanceIdentifier}'

Cloud defenses: AWS Config rules, Checkov/tfsec on all Terraform, enforce IMDSv2, Security Hub enabled.

A06: Vulnerable and Outdated Components

Cloud twist: Vulnerable base images in Docker, outdated Lambda runtimes, unpatched AMIs.

Cloud defenses: Trivy image scanning, Dependabot auto-updates, ECR image scanning, Lambda runtime deprecation alerts.

A07: Identification and Authentication Failures

Cloud twist: Overly long-lived access keys, no MFA on IAM users, shared credentials between services, no token rotation.

# Find access keys older than 90 days
aws iam generate-credential-report
aws iam get-credential-report --query 'Content' --output text | \
  base64 -d | awk -F, 'NR>1 && $9!="N/A" && $11!="N/A" {print $1,$9}'

Cloud defenses: Enforce MFA, use IAM roles instead of access keys, rotate credentials automatically, short-lived tokens.

A08: Software and Data Integrity Failures

Cloud twist: Unsigned Docker images, unverified CI/CD artifacts, no provenance for deployed code.

Cloud defenses: cosign for image signing, SLSA provenance, Kubernetes admission controllers that verify signatures.

A09: Security Logging and Monitoring Failures

Cloud twist: CloudTrail not enabled in all regions, no VPC Flow Logs, no alerts on high-risk API calls.

Cloud defenses: Multi-region CloudTrail, CloudWatch alarms for security events, centralized SIEM, automated alerting.

A10: Server-Side Request Forgery (SSRF)

This is the most dangerous cloud-specific vulnerability. SSRF in a cloud environment gives attackers access to the Instance Metadata Service (IMDS) and temporary IAM credentials.

SSRF Cloud Attack Flow

# The classic SSRF attack in cloud
# Attacker sends: url=http://169.254.169.254/latest/meta-data/iam/security-credentials/

# ❌ Vulnerable code — fetches any URL
import requests

def handler(event, context):
    url = event['queryStringParameters']['url']
    response = requests.get(url)  # SSRF!
    return {'statusCode': 200, 'body': response.text}

# ✅ Defended — allowlist + IMDSv2
import requests
from urllib.parse import urlparse

ALLOWED_HOSTS = ['api.example.com', 'cdn.example.com']

def handler(event, context):
    url = event['queryStringParameters']['url']
    parsed = urlparse(url)

    if parsed.hostname not in ALLOWED_HOSTS:
        return {'statusCode': 403, 'body': 'Blocked'}
    if parsed.hostname.startswith('169.254.') or parsed.hostname == 'metadata.google.internal':
        return {'statusCode': 403, 'body': 'Blocked'}

    response = requests.get(url, timeout=5)
    return {'statusCode': 200, 'body': response.text}

Critical defense: Enforce IMDSv2 on all EC2 instances. IMDSv2 requires a session token that can’t be obtained via a simple GET request, effectively blocking most SSRF-based credential theft.

# Enforce IMDSv2 on all instances
aws ec2 modify-instance-metadata-options \
  --instance-id i-1234567890abcdef0 \
  --http-tokens required \
  --http-endpoint enabled

Cloud-Specific Mitigations Summary

OWASP Cloud Defense AWS Service
A01 IAM least privilege IAM Access Analyzer
A02 Encrypt everything KMS, ACM
A03 Validate all event inputs WAF, input validation
A05 Continuous compliance Config, Security Hub
A06 Scan everything ECR scanning, Trivy
A09 Log everything CloudTrail, VPC Flow Logs
A10 IMDSv2 + URL allowlists Instance metadata config

Key Takeaways

  1. SSRF is the #1 cloud risk — enforce IMDSv2 on every instance, no exceptions
  2. Misconfiguration > exploitation — most cloud breaches are misconfig, not zero-days
  3. Lambda event injection is real — treat all event sources as untrusted input
  4. IAM IS access control — broken IAM = broken access control in the cloud
  5. Encrypt by default — KMS for rest, TLS for transit, no exceptions
  6. Log everything, alert on anomalies — CloudTrail is your cloud security backbone
Share

Related Posts

Supply Chain Security — Protecting Your Software Pipeline

Supply Chain Security — Protecting Your Software Pipeline

In 2024, a single malicious contributor nearly compromised every Linux system on…

Security Ticketing and Incident Response

Security Ticketing and Incident Response

The worst time to figure out your incident response process is during an…

Security Mindset for Engineers — Think Like an Attacker

Security Mindset for Engineers — Think Like an Attacker

Most engineers think about security the way they think about flossing — they…

Secrets Management — Vault, SSM, and Secrets Manager

Secrets Management — Vault, SSM, and Secrets Manager

I’ve watched a production database get wiped because someone committed a root…

Penetration Testing Basics for Developers

Penetration Testing Basics for Developers

Most developers think of penetration testing as something a separate security…

Dependency Vulnerability Detection at Scale

Dependency Vulnerability Detection at Scale

The average application has over 200 transitive dependencies. Each one is code…

Latest Posts

AI Video Generation in 2025 — Models, Costs, and How to Build a Cost-Effective Pipeline

AI Video Generation in 2025 — Models, Costs, and How to Build a Cost-Effective Pipeline

AI video generation went from “cool demo” to “usable in production” in 2024-202…

AI Models in 2025 — Cost, Capabilities, and Which One to Use

AI Models in 2025 — Cost, Capabilities, and Which One to Use

Choosing the right AI model is one of the most impactful decisions you’ll make…

AI Image Generation in 2025 — Models, Costs, and How to Optimize Spend

AI Image Generation in 2025 — Models, Costs, and How to Optimize Spend

Generating one image with AI costs between $0.002 and $0.12. That might sound…

AI Agents Demystified — It's Just Automation With a Better Brain

AI Agents Demystified — It's Just Automation With a Better Brain

Let’s cut through the noise. If you read Twitter or LinkedIn, you’d think “AI…

AI Coding Assistants in 2025 — Every Tool Compared, and Which One to Actually Use

AI Coding Assistants in 2025 — Every Tool Compared, and Which One to Actually Use

Two years ago, AI coding meant one thing: GitHub Copilot autocompleting your…

Supply Chain Security — Protecting Your Software Pipeline

Supply Chain Security — Protecting Your Software Pipeline

In 2024, a single malicious contributor nearly compromised every Linux system on…