Cloud Security Guide: AWS, Azure & GCP Misconfigurations 2025
On this page
Cloud Security Landscape 2025
Statistics
- 98% of breaches involve cloud misconfigurations (Gartner)
- Average cost: $4.9 million per breach (IBM)
- Time to detect: 236 days average
- Public bucket exposure: 45% of S3 buckets allow public access
AWS Security
1. S3 Bucket Misconfiguration
❌ VULNERABLE: Public S3 Bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::company-data/*"
}
]
}
Risks:
- Public data exposure
- Credential leaks
- Personal information exposure
- Malware distribution
Real Breach (Parler 2021):
- Misconfigured S3 buckets exposed user data
- 70GB of private information
- Caused platform shutdown
✅ Secure Configuration
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::secure-bucket",
"arn:aws:s3:::secure-bucket/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/app-user"
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::secure-bucket/*"
}
]
}
S3 Security Checklist
# Block public access globally
aws s3api put-public-access-block \
--bucket my-bucket \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
# Enable versioning
aws s3api put-bucket-versioning \
--bucket my-bucket \
--versioning-configuration Status=Enabled
# Enable encryption
aws s3api put-bucket-encryption \
--bucket my-bucket \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}]
}'
# Enable logging
aws s3api put-bucket-logging \
--bucket my-bucket \
--bucket-logging-status '{
"LoggingEnabled": {
"TargetBucket": "logging-bucket",
"TargetPrefix": "s3-logs/"
}
}'
# Block unencrypted uploads
aws s3api put-bucket-policy \
--bucket my-bucket \
--policy file://deny-unencrypted.json
2. IAM (Identity and Access Management) Vulnerabilities
❌ VULNERABLE: Overly Permissive Role
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
Risks:
- Privilege escalation
- Lateral movement
- Data exfiltration
- Infrastructure destruction
✅ SECURE: Least Privilege
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RDSAccess",
"Effect": "Allow",
"Action": [
"rds:DescribeDBInstances",
"rds-db:connect"
],
"Resource": "arn:aws:rds:us-east-1:123456789012:db/mydb",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "us-east-1"
}
}
},
{
"Sid": "S3ReadOnly",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::app-data",
"arn:aws:s3:::app-data/*"
]
},
{
"Sid": "ExplicitDeny",
"Effect": "Deny",
"Action": [
"iam:*",
"ec2:TerminateInstances",
"rds:DeleteDBInstance"
],
"Resource": "*"
}
]
}
IAM Security Best Practices
# Audit IAM users
aws iam list-users --output table
# Find unused credentials (not used in 90+ days)
aws iam get-credential-report | grep -i "password_enabled"
# Enable MFA for root account
aws iam enable-mfa-device \
--user-name root \
--serial-number arn:aws:iam::123456789012:mfa/root \
--authentication-code1 123456 \
--authentication-code2 654321
# Use temporary credentials (STS, not long-term keys)
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/app-role \
--role-session-name app-session
# Rotate access keys every 90 days
3. Secrets Management
❌ VULNERABLE: Secrets in Code/Environment
// .env file in repository
DATABASE_URL=mongodb://user:pass@db.example.com
API_KEY=sk-1234567890abcdef
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Risks:
- Credential exposure via git history
- Source code repository breaches
- CI/CD pipeline compromises
- Automated credential scanning by attackers
✅ SECURE: AWS Secrets Manager
const AWS = require('aws-sdk');
const secretsManager = new AWS.SecretsManager({
region: 'us-east-1'
});
async function getSecret(secretName) {
try {
const data = await secretsManager.getSecretValue({
SecretId: secretName
}).promise();
return JSON.parse(data.SecretString);
} catch (error) {
console.error('Error retrieving secret:', error);
throw error;
}
}
// Usage
const dbCredentials = await getSecret('prod/database');
const apiKey = await getSecret('prod/api-key');
✅ SECURE: HashiCorp Vault
const vault = require('node-vault')({
endpoint: 'https://vault.example.com',
token: process.env.VAULT_TOKEN
});
async function getSecret(path) {
try {
const secret = await vault.read(path);
return secret.data.data;
} catch (error) {
console.error('Vault error:', error);
throw error;
}
}
// Usage
const dbCreds = await getSecret('secret/data/prod/database');
4. CloudTrail & Monitoring
Enable CloudTrail for Auditing
# Enable CloudTrail
aws cloudtrail create-trail \
--name companyTrail \
--s3-bucket-name cloudtrail-logs
# Enable logging
aws cloudtrail start-logging \
--trail-name companyTrail
# Search for suspicious activities
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=DeleteBucket \
--max-results 10
Azure Security
1. Storage Account Misconfiguration
❌ VULNERABLE
Azure blob container with public access level set to "Blob"
✅ SECURE: Private with SAS Tokens
# Create storage account with secure defaults
az storage account create \
--name securestorage1234 \
--resource-group myResourceGroup \
--kind BlobStorage \
--access-tier Hot \
--https-only true \
--min-tls-version TLS1_2
# Set container access to Private
az storage container create \
--name sensitive-data \
--account-name securestorage1234 \
--public-access off
# Create SAS token with time limit
az storage account generate-sas \
--account-name securestorage1234 \
--account-key (azure storage account keys list) \
--expiry 2025-02-16T12:00:00Z \
--permissions racwd \
--resource-types sco \
--services bfqt
2. Azure RBAC (Role-Based Access Control)
Principle of Least Privilege
# Create custom role with minimal permissions
az role definition create --role-definition '{
"Name": "App Reader",
"Description": "Read-only access to app resources",
"Type": "CustomRole",
"Permissions": [
{
"Actions": ["*/read"],
"NotActions": []
}
],
"AssignableScopes": ["/subscriptions/..."]
}'
# Assign role to managed identity
az role assignment create \
--assignee-object-id (ObjectId) \
--role "App Reader" \
--scope /subscriptions/.../resourceGroups/myResourceGroup
GCP Security
1. Firestore Database Security
❌ VULNERABLE: Open to Public
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
✅ SECURE: Authenticated Only
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Require authentication
match /{document=**} {
allow read, write: if request.auth != null;
}
// User can only read/write their own data
match /users/{userId}/documents/{doc=**} {
allow read, write: if request.auth.uid == userId;
}
}
}
Multi-Cloud Security Checklist
- Enable encryption at rest and in transit
- Implement IAM/RBAC with least privilege
- Use managed secrets (Secrets Manager, Vault, Key Vault)
- Enable logging and monitoring (CloudTrail, Azure Monitor)
- Enable MFA for all accounts
- Regularly audit and rotate credentials
- Implement VPC/Vnet isolation
- Use DDoS protection
- Enable threat detection (GuardDuty, Azure Sentinel)
- Regular penetration testing
Cloud Security Tools
| Tool | Purpose | Cloud | Cost |
|---|---|---|---|
| Prowler | AWS security audit | AWS | Free |
| ScoutSuite | Multi-cloud assess | All | Free |
| CloudMapper | AWS network visualization | AWS | Free |
| Dome9 | Cloud security posture | All | Paid |
| CloudSploit | AWS infrastructure checks | AWS | Free |
Real-World Breach Cases
Capital One (2019)
- WAF bypass + metadata endpoint access
- 100M customers affected
- Cost: $80M settlement
Twitter (2020)
- OAuth token theft via social engineering
- Led to cryptocurrency scam
- Reinforced need for access controls
Key Takeaways
- Default to private - Make public exceptions explicit
- Least privilege - Grant minimal necessary permissions
- Rotate credentials - Monthly for long-term keys
- Monitor everything - CloudTrail, logs, anomalies
- Encrypt + Audit - Non-negotiable for compliance
Published by SecureCodeReviews
This article is part of our original AI security and cybersecurity content library. We show publish and update dates, keep company and policy pages public, and update important guidance when material changes affect readers.
Need a cloud security review before rollout?
We review IAM, network exposure, storage security, deployment posture, and the misconfigurations that usually get missed in fast-moving teams.
Advertisement
Free Security Tools
Try our tools now
Expert Services
Get professional help
OWASP Top 10
Learn the top risks
Related Articles
Cloud Security in 2025: Comprehensive Guide for AWS, Azure & GCP
Deep-dive into cloud security best practices across all three major providers. Covers IAM, network security, data encryption, compliance, and real-world misconfigurations that led to breaches.
Security Misconfiguration Jumped to #2 in OWASP 2025: Complete Prevention Guide
Security misconfiguration surged from #5 to #2 in the OWASP Top 10 2025. Cloud misconfigs, default credentials, verbose errors, and unnecessary features expose millions of applications. This guide covers the most exploited misconfigurations with fixes.
Multi-Cloud Security Strategy: Unified Controls for AWS, Azure & GCP
87% of enterprises use multi-cloud. This guide provides a unified security strategy — identity federation, network segmentation, CSPM, centralized logging, and consistent policy enforcement across AWS, Azure, and GCP.