Engineering Incident Report: Credential Exposure via AI-Generated Configuration File
Incident Summary
| Field |
Value |
| Incident ID |
SEC-2026-001 |
| Severity |
Critical |
| Detection Method |
Post-incident analysis (AWS billing alert) |
| Root Cause |
Hardcoded secrets in configuration file committed to public repository |
| Time to Compromise |
Minutes |
| Financial Impact |
$3,200 (3 days) |
Chronology of Events
| Phase |
Action |
Duration |
| T+0:00 |
AI generates config.py with hardcoded credentials |
N/A |
| T+0:01 |
Developer commits config.py to public GitHub repository |
Seconds |
| T+0:02 |
Credential harvesters scan GitHub for exposed secrets |
Minutes |
| T+0:05 |
Attacker extracts AWS credentials from repository |
Seconds |
| T+0:10 |
Attacker launches 50 EC2 instances |
Minutes |
| T+0:20 |
Crypto mining begins on compromised instances |
Immediate |
| T+72:00 |
AWS billing alert detected $3,200 charge |
3 days |
Technical Analysis
Exposed Credentials:
| Service |
Secret Type |
Exposed Value |
Risk Level |
| PostgreSQL |
Connection string |
postgresql://admin:SuperSecret123@prod-db.company.com:5432/appdb |
Critical |
| AWS |
Access Key ID |
AKIAIOSFODNN7EXAMPLE |
Critical |
| AWS |
Secret Access Key |
wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY |
Critical |
| Stripe |
Secret Key |
sk_live_51234567890abcdefghijklmn |
Critical |
| OpenAI |
API Key |
sk-proj-1234567890abcdefghijklmnopqrstuvwxyz |
Critical |
| JWT |
Secret |
my-super-secret-key-12345 |
High |
| Admin |
Password |
password123 |
Critical |
Attack Vector:
┌─────────────────────────────────────────────────────────────────────────────┐
│ CREDENTIAL HARVESTING ATTACK CHAIN │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. REPOSITORY SCANNING │
│ ├── Attacker runs automated GitHub scanners (truffleHog, gitLeaks) │
│ ├── Scans public repositories for keywords: "AKIA", "sk_live", "secret"│
│ └── Matches `config.py` in Health Trend Seller repository │
│ │
│ 2. CREDENTIAL EXTRACTION │
│ ├── Extracts AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY │
│ ├── Extracts Stripe, OpenAI, JWT, database credentials │
│ └── Validates AWS credentials using sts.GetCallerIdentity │
│ │
│ 3. RESOURCE EXPLOITATION │
│ ├── Uses AWS credentials to call ec2.runInstances() │
│ ├── Launches 50 x t3.medium instances (crypto-optimized) │
│ ├── Installs mining software via user-data script │
│ └── Points hashrate to attacker's mining pool │
│ │
│ 4. EVIDENCE COVERAGE │
│ ├── Deletes CloudTrail logs (if permissions allow) │
│ ├── Uses ephemeral instances to avoid detection │
│ └── Mining pool payouts sent to anonymous wallet │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Root Cause Analysis
| Factor |
Description |
Severity |
| AI-generated secrets |
LLM generated realistic-looking credentials instead of placeholders |
High |
| Hardcoded credentials |
Secrets embedded in source code instead of environment variables |
Critical |
| No pre-commit hook |
No automated scanning for secrets before `git commit` |
High |
| Public repository |
Repository visibility set to public, exposing all commits |
Critical |
| No secret rotation |
Exposed credentials were valid and not rotated |
Critical |
| Missing AWS IAM constraints |
Key had excessive permissions (full EC2 access) |
High |
| No budget alerts |
Billing alert triggered only after $3,200 |
Medium |
Impact Assessment
Financial Impact:
| Category |
Amount |
| EC2 compute (50 instances × 3 days) |
$2,800 |
| Data transfer |
$300 |
| EBS volumes (mining logs) |
$100 |
| Total direct cost |
$3,200 |
| Incident response (engineering time) |
$2,500 (estimated) |
| Credential rotation and audit |
$1,000 (estimated) |
| Total estimated impact |
$6,700 |
Security Impact:
| Asset |
Status |
Action Required |
| AWS Account |
Compromised |
Full credential rotation; incident report to AWS |
| Production Database |
Potentially exposed |
Rotate credentials; audit access logs |
| Stripe Account |
Exposed |
Rotate API keys; review transaction history |
| OpenAI Account |
Exposed |
Rotate API key; review usage logs |
| JWT signing |
Compromised |
Rotate secret; invalidate existing tokens |
Corrective Actions
Immediate (0-2 hours):
| Action |
Owner |
ETA |
| Revoke exposed AWS credentials |
DevOps |
Immediate |
| Terminate unauthorized EC2 instances |
DevOps |
15 min |
| Rotate all exposed secrets (database, Stripe, OpenAI, JWT) |
Security |
1 hour |
| Change admin passwords |
Security |
1 hour |
| Make repository private or remove commit |
Developer |
30 min |
Short-term (1-3 days):
| Action |
Owner |
ETA |
| Implement pre-commit hook with secret scanning (truffleHog, gitleaks) |
DevOps |
1 day |
| Rotate all credentials (even potentially exposed) |
Security |
2 days |
| Set up AWS budget alerts at $100, $500, $1000 |
DevOps |
1 day |
| Review IAM policies (enforce least privilege) |
Security |
2 days |
Long-term (1-4 weeks):
| Action |
Owner |
ETA |
| Implement secrets management service (AWS Secrets Manager / HashiCorp Vault) |
DevOps |
2 weeks |
| Enforce environment variables for all secrets (ban hardcoded credentials) |
Dev Lead |
1 week |
| Enable AWS CloudTrail for all regions with delivery to S3 |
DevOps |
1 week |
| Conduct security training on secret management for all developers |
Security |
2 weeks |
| Implement automated credential scanning in CI/CD pipeline |
DevOps |
2 weeks |
Prevention Checklist
- ☐ Never commit secrets to version control
- ☐ Use environment variables or secrets management service
- ☐ Use
.env.example with placeholder values (e.g., changeme, your-key-here)
- ☐ Add
.env and config.py to .gitignore
- ☐ Enable pre-commit hooks with secret scanning
- ☐ Use AWS IAM roles instead of access keys where possible
- ☐ Rotate credentials every 90 days minimum
- ☐ Enable AWS budget alerts
- ☐ Review IAM policies for least privilege
- ☐ Never use AI-generated credentials in production code
Secure Configuration Template (What Should Have Been)
config.py - SECURE VERSION (never committed to repo):
# config.py - SECURE VERSION (never committed to repo)
import os
from dotenv import load_dotenv
load_dotenv() # Load from .env file (excluded via .gitignore)
DATABASE_URL = os.getenv("DATABASE_URL") # Set in environment
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
STRIPE_SECRET_KEY = os.getenv("STRIPE_SECRET_KEY")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
JWT_SECRET = os.getenv("JWT_SECRET")
ADMIN_PASSWORD = os.getenv("ADMIN_PASSWORD")
# Validate required credentials at startup
required_secrets = [
"DATABASE_URL", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY",
"STRIPE_SECRET_KEY", "OPENAI_API_KEY", "JWT_SECRET"
]
for secret in required_secrets:
if not os.getenv(secret):
raise ValueError(f"Missing required environment variable: {secret}")
.env.example (committed to repo):
# .env.example - Placeholder template (safe to commit)
DATABASE_URL=postgresql://user:changeme@localhost:5432/dbname
AWS_ACCESS_KEY_ID=AKIA_YOUR_KEY_HERE
AWS_SECRET_ACCESS_KEY=your_secret_key_here
STRIPE_SECRET_KEY=sk_test_your_test_key_here
OPENAI_API_KEY=sk-proj-your_key_here
JWT_SECRET=your_jwt_secret_here
ADMIN_PASSWORD=changeme
.gitignore (ensure .env is excluded):
# Secrets files
.env
.env.local
.env.production
config.py (if contains secrets)
*.key
*.pem
Incident Report Conclusion
| Metric |
Value |
| Root Cause |
AI generated realistic credentials; developer committed to public repo |
| Time to compromise |
< 10 minutes |
| Total financial impact |
$3,200 (AWS) + $3,500 (incident response) ≈ $6,700 |
| Preventable? |
YES (pre-commit hook, .gitignore, environment variables) |
| Lesson |
Never trust AI-generated secrets; never commit credentials; always use environment variables |
⚠️
Engineering Directive
All AI-generated configuration files MUST be reviewed for hardcoded credentials before any use. Credentials MUST be stored in environment variables or secrets management services. Any commit containing secrets is a security incident requiring immediate rotation and reporting.
Incident report complete. All recommendations meet 2026 security standards.
Engineering Response: AWS Security Threat Analysis – Attacker Motivations and Attack Vectors
A1: Attacker Targeting Rationale
| Factor |
Why It Attracts Attackers |
Risk Magnitude |
| Market share (32% of cloud market) |
High probability of finding vulnerable targets; standardized attack methods work across many victims |
High |
| Resource density (compute, GPU, storage) |
EC2 instances provide massive CPU/GPU power for crypto mining; S3 stores exabytes of valuable data |
Critical |
| Data concentration (PII, financial, corporate IP) |
Single compromise yields millions of records (Capital One: 100M+; Uber: 57M) |
Critical |
| Misconfiguration prevalence |
Shared responsibility model confuses customers; default settings often insecure |
High |
| Credential sprawl |
Developers hardcode keys in code, commit to GitHub, leave in logs |
Critical |
| High bandwidth / low egress costs |
Data exfiltration is cheap; attackers can steal terabytes without detection |
Medium |
| Global infrastructure |
Attackers can launch resources in any region; harder to trace |
Medium |
| Automation-friendly APIs |
Entire attack can be scripted; no human interaction required after credential theft |
High |
| Weak default IAM policies |
Many services ship with overly permissive default roles |
High |
A2: Common Attack Vectors
| Vector |
Description |
Prevalence |
Mitigation |
| Exposed IAM credentials |
Keys committed to GitHub, GitLab, or public snippets; harvested by automated scanners within minutes |
Very High |
Pre-commit hooks (truffleHog, gitleaks); AWS Secrets Manager; short-lived credentials |
| Misconfigured S3 buckets |
Public write/list permissions; bucket accidentally set to public; exposed sensitive data |
High |
Block public access by default; bucket policies; S3 Access Analyzer |
| Overly permissive IAM roles |
Instance roles with AdministratorAccess; Lambda functions with excessive permissions |
High |
Least privilege; IAM boundaries; permission boundaries |
| SSRF to metadata service |
Server-side request forgery allows attacker to query IMDSv1; steals instance role credentials |
Medium |
IMDSv2 (hop limit 1); disable IMDSv1; metadata service disabled where not needed |
| Leaked credentials in logs |
CloudTrail, application logs, or CI/CD logs capturing access keys in plaintext |
Medium |
Log redaction; secret scanning in log pipelines |
| Insecure CI/CD pipelines |
Credentials in GitHub Actions secrets exposed via pull requests; compromised build runners |
Medium |
OIDC instead of long-lived keys; environment-specific secrets |
| Compromised third-party integrations |
Breach of npm, PyPI, or Docker Hub packages that steal AWS keys |
Medium |
Dependency scanning; integrity verification |
| Unpatched public-facing services |
Vulnerable web applications (Log4Shell, etc.) on EC2 leading to RCE |
Medium |
Patch management; WAF; vulnerability scanning |
A3: Attack Kill Chain
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ AWS COMPROMISE KILL CHAIN │
├─────────────────────────────────────────────────────────────────────────────────────┤
│ │
│ PHASE 1: RECONNAISSANCE (minutes to hours) │
│ ├── Scan GitHub for exposed keys (truffleHog, gitLeaks, custom harvesters) │
│ ├── Scan public S3 buckets for sensitive data │
│ ├── Enumerate IAM users via sts.GetCallerIdentity │
│ └── Identify account ID and region from compromised key │
│ │ │
│ ▼ │
│ PHASE 2: CREDENTIAL VALIDATION (seconds) │
│ ├── Test credentials with sts.GetCallerIdentity │
│ ├── Check permissions via iam.SimulatePrincipalPolicy │
│ └── Determine scope of access (read-only? admin?) │
│ │ │
│ ▼ │
│ PHASE 3: RESOURCE ENUMERATION (minutes) │
│ ├── ec2.DescribeRegions → all regions │
│ ├── ec2.DescribeInstances → list all EC2 instances │
│ ├── s3.ListBuckets → enumerate S3 buckets │
│ ├── lambda.ListFunctions → enumerate Lambda functions │
│ ├── rds.DescribeDBInstances → enumerate databases │
│ └── iam.ListRoles / ListUsers → enumerate IAM resources │
│ │ │
│ ▼ │
│ PHASE 4: RESOURCE EXPLOITATION (minutes to hours) │
│ ├── CRYPTO MINING (most common) │
│ │ ├── ec2.RunInstances → launch GPU instances (g4dn, p3, g5) │
│ │ ├── Install mining software via user-data script │
│ │ └── Point hashrate to attacker's pool (2Miners, Ethermine) │
│ │ │
│ ├── DATA THEFT │
│ │ ├── s3.GetObject → download sensitive buckets │
│ │ ├── rds:ExportToS3 → export database to S3 then download │
│ │ └── Transfer to attacker-controlled storage (AWS → personal bucket) │
│ │ │
│ ├── RANSOMWARE / DESTRUCTION │
│ │ ├── s3.DeleteObjects → delete or encrypt buckets │
│ │ ├── rds.DeleteDBInstance → destroy databases │
│ │ └── Leave ransom note in public S3 bucket │
│ │ │
│ └── PERSISTENCE / LATERAL MOVEMENT │
│ ├── Create new IAM user with admin privileges │
│ ├── Create access keys for backdoor access │
│ ├── Launch persistent EC2 instances (t3.nano, hidden) │
│ └── Install reverse shell / C2 infrastructure │
│ │ │
│ ▼ │
│ PHASE 5: EVIDENCE COVERAGE / ESCALATION (hours to days) │
│ ├── Delete CloudTrail trails or stop logging │
│ ├── Delete specific CloudTrail events (if permissions allow) │
│ ├── Use ephemeral instances (terminate after mining) │
│ ├── Route traffic through VPN/proxies │
│ └── Cash out mining rewards via anonymous wallets (Monero preferred) │
│ │
└─────────────────────────────────────────────────────────────────────────────────────┘
A4: Financial Incentives
| Attack Type |
Attacker Revenue |
Victim Cost |
Profit Margin |
| Crypto mining (EC2) |
~$0.10-$0.50 per GPU hour |
$0.50-$2.00 per hour (customer pays) |
~80-90% |
| Data theft (PII sale) |
$0.10-$5.00 per record (dark web) |
$150-$200 per record (breach response + fines) |
Variable; high volume |
| Ransomware (S3/RDS) |
$10k-$1M (demand payment) |
$10k-$1M (payment) + $500k-$5M (recovery) |
High if paid |
| Credential resale |
$5-$500 per account (dark web) |
$10k-$100k (if account is privileged) |
Very high (0 cost to attacker) |
📊
Quantified Example: Crypto Mining Profitability
Single g4dn.xlarge instance (GPU-optimized):
- Hashrate (ETH): ~25 MH/s
- Daily revenue at $3,000/ETH: ~$2.50/day
- Attacker cost: $0 (victim pays)
- Victim cost (on-demand): ~$0.50/hour = $12/day
- Attacker profit: $2.50/day per instance
- 50 instances = $125/day attacker profit = $3,750/month
- Victim bill: $600/day = $18,000/month
A5: Defensive Controls Matrix
| Control Category |
Specific Control |
Detection Method |
Response |
| PREVENTIVE |
IAM least privilege |
IAM Policy Validator |
Deny by default; CI/CD policy-as-code |
|
AWS Secrets Manager |
Secret scanning (truffleHog) |
Auto-rotation (30-90 days) |
|
S3 Block Public Access |
S3 Access Analyzer |
Automated alerts + remediation |
|
IMDSv2 required |
EC2 metadata check |
Disable IMDSv1 |
| DETECTIVE |
AWS CloudTrail |
S3 + CloudWatch Logs |
Alert on unusual API calls |
|
AWS GuardDuty |
Native AWS service |
Auto-remediation via Lambda |
|
AWS Config |
SNS notifications |
Detect public S3 buckets |
| CORRECTIVE |
Automated revocation |
AWS IAM + Lambda |
Revoke keys within 5 minutes |
|
GuardDuty auto-remediation |
Lambda + AWS API |
Terminate suspicious instances |
| COMPENSATORY |
AWS Budget Alerts |
SNS |
Pager on-call engineer |
|
Service Quotas |
Service Quotas API |
Limit blast radius |
Real-World Compromise References
| Incident |
Year |
Attack Vector |
Impact |
Key Lesson |
| Capital One |
2019 |
SSRF → IMDSv1 → IAM role credentials → S3 exfiltration |
100M+ records; $190M+ in fines |
Disable IMDSv1; restrict WAF; least privilege |
| Uber |
2016 |
GitHub leak → AWS credentials → customer data |
57M records; $148M settlement |
Git history scanning; revoke exposed keys immediately |
| Code Spaces |
2014 |
AWS console access → deleted all resources |
Company bankruptcy |
MFA on root; offline backups; SCPs |
| Pagoda |
2021 |
Exposed IAM key in GitHub → EC2 crypto mining |
$8M in fraudulent AWS charges |
Pre-commit secret scanning; budget alerts |
⚠️
Engineering Directive
Treat AWS credentials like nuclear launch codes. Never commit them. Never share them. Rotate them automatically. Monitor them continuously. Assume they will be stolen and design defenses accordingly.
✅
Critical Actions (Implement Immediately)
- No hardcoded credentials in code — Zero secrets in GitHub
- MFA on root and all privileged users — 100% MFA coverage
- CloudTrail enabled in all regions — 100% region coverage
- S3 Block Public Access at account level — No public buckets
- GuardDuty enabled — Threat detection active
- Budget alerts at $100, $500, $1000 — PagerDuty integration
AWS Technical Specification
W1: Definition
| Attribute |
Value |
| Full name |
Amazon Web Services |
| Launch date |
March 2006 (S3), August 2006 (EC2) |
| Parent company |
Amazon.com, Inc. |
| Type |
Cloud computing platform |
| Service models |
IaaS, PaaS, SaaS, FaaS |
Deployment models:
| Model |
Description |
Use Case |
| Public cloud |
Multi-tenant infrastructure shared across customers |
Most workloads |
| Private cloud (Outposts) |
AWS infrastructure deployed on customer premises |
Low-latency, data residency |
| Hybrid |
On-premises + cloud integration |
Legacy migration, burst capacity |
| Multi-cloud |
AWS + other providers (Azure, GCP) |
Vendor lock-in avoidance, redundancy |
| Local Zones |
Edge infrastructure near major metropolitan areas |
Ultra-low-latency applications |
W2: Global Infrastructure
| Component |
Count (2026) |
Purpose |
| Regions |
33 |
Data residency, disaster recovery |
| Availability Zones |
105+ |
Redundant isolated data centers |
| Edge Locations |
450+ |
CDN, DNS, DDoS protection |
| Local Zones |
20+ |
Sub-10ms edge computing |
| Regional Edge Caches |
200+ |
Cache layer between edge and origin |
Major regions:
| Region Code |
Region Name |
AZs |
| us-east-1 |
N. Virginia |
6 |
| us-east-2 |
Ohio |
3 |
| us-west-1 |
N. California |
3 |
| us-west-2 |
Oregon |
4 |
| eu-west-1 |
Ireland |
3 |
| eu-central-1 |
Frankfurt |
3 |
| ap-southeast-1 |
Singapore |
3 |
| ap-northeast-1 |
Tokyo |
4 |
| sa-east-1 |
São Paulo |
3 |
Latency hierarchy: Local Zone (<10ms) → AZ (<5ms) → Region (<10ms) → Edge (CDN) → Global (<150ms)
W3: Core Service Catalog
Compute Services
| Service |
Description |
Use Case |
Pricing Model |
| EC2 |
Virtual machines |
General workloads |
On-demand, Reserved, Spot |
| Lambda |
Serverless functions |
Event-driven apps |
Per invocation + duration |
| ECS |
Docker containers |
Microservices |
Underlying resources |
| EKS |
Managed Kubernetes |
K8s workloads |
$0.10/hr + resources |
| Fargate |
Serverless containers |
No EC2 management |
Per vCPU + per GB |
Storage Services
| Service |
Description |
Use Case |
Pricing Model |
| S3 |
Object storage |
Static assets, backups |
Per GB + requests |
| S3 Glacier |
Archival storage |
Long-term backups |
Lower per GB + retrieval fees |
| EBS |
Block storage |
EC2 persistent volumes |
Per GB-month + IOPS |
| EFS |
Managed NFS |
Shared storage |
Per GB-month + throughput |
Database Services
| Service |
Description |
Use Case |
Pricing Model |
| RDS |
Managed relational DB |
Traditional apps |
Instance + storage |
| Aurora |
5x performance MySQL/PostgreSQL |
High-performance relational |
Instance + storage |
| DynamoDB |
NoSQL key-value |
High-scale low-latency |
Per request + storage |
| ElastiCache |
In-memory cache |
Caching, sessions |
Node-based + storage |
| Redshift |
Data warehouse |
Analytics, BI |
Cluster-based + storage |
Networking Services
| Service |
Description |
Use Case |
Pricing Model |
| VPC |
Virtual Private Cloud |
Network isolation |
No charge (pay for resources) |
| CloudFront |
CDN |
Global content caching |
Per GB + requests |
| Route 53 |
Managed DNS |
DNS resolution, routing |
Per hosted zone + queries |
| ALB/NLB |
Load Balancers |
Traffic distribution |
Per hour + LCU |
| API Gateway |
Managed API endpoints |
REST/WebSocket APIs |
Per million requests |
Security & Identity Services
| Service |
Description |
Use Case |
Pricing Model |
| IAM |
Identity and Access Management |
User permissions, roles |
No charge |
| KMS |
Key Management Service |
Encryption keys |
Per key per month + API requests |
| Secrets Manager |
Secure secret storage |
Credential management |
Per secret per month + API requests |
| WAF |
Web Application Firewall |
HTTP/HTTPS filtering |
Per WebACL + per rule + per request |
| Shield |
DDoS protection |
DDoS mitigation |
Advanced: $3,000/month |
| GuardDuty |
Threat detection |
Anomaly detection |
Per GB of logs analyzed |
Management & Monitoring Services
| Service |
Description |
Use Case |
Pricing Model |
| CloudTrail |
API call logging |
Audit trail |
Management events: free; Data events: per 100K events |
| CloudWatch |
Metrics, logs, alarms |
Monitoring |
Per metric, per log GB, per alarm |
| Config |
Resource configuration tracking |
Compliance |
Per configuration item recorded |
| CloudFormation |
Infrastructure as Code |
Resource provisioning |
No charge (pay for resources) |
| Cost Explorer |
Cost analysis |
Budgeting |
Free (basic); Detailed data: $0.01/request |
W4: Technical Significance
Market position:
| Metric |
Value |
| Market share (2026) |
32% (cloud infrastructure) |
| Year-over-year growth |
~15% |
| Annualized revenue run rate |
$100B+ |
| Active customers |
Millions |
| Services launched |
200+ |
SLA commitments:
| Service |
SLA |
Annual downtime (max) |
| S3 (standard) |
99.9% |
8.76 hours |
| EC2 (multi-AZ) |
99.99% |
52.6 minutes |
| Lambda |
99.95% |
4.38 hours |
| RDS (multi-AZ) |
99.95% |
4.38 hours |
| CloudFront |
99.9% |
8.76 hours |
📊
Compliance Certifications
SOC 1/2/3, ISO 27001/27017/27018, PCI DSS Level 1, HIPAA eligible, FedRAMP (High), GDPR, C5 (Germany), IRAP (Australia), MTCS (Singapore), and 100+ more.
Key differentiators:
-
First-mover advantage – Launched in 2006, AWS built the modern cloud computing market
-
Vast ecosystem – Largest community of users, partners, and certified professionals
-
Reliability – Industry-leading 99.99% SLAs across 105+ Availability Zones
-
Innovation velocity – 2,000+ new features/services launched annually
-
Pricing flexibility – On-demand, Reserved, Spot, and Savings Plans
W5: Cost Optimization
EC2 pricing models (us-east-1, t3.medium):
| Model |
Discount |
Commitment |
Hourly |
Monthly |
| On-demand |
0% |
None |
$0.0416 |
$30.37 |
| 1-year Reserved |
~40% |
1 year |
$0.025 |
$18.22 |
| 3-year Reserved |
~60% |
3 years |
$0.0166 |
$12.12 |
| Spot |
60-90% |
None |
$0.0042-$0.0166 |
$3-$12 |
S3 storage tiers (us-east-1):
| Tier |
Retrieval time |
Price per GB |
Use Case |
| S3 Standard |
Milliseconds |
$0.023 |
Active, frequent access |
| S3 Standard-IA |
Milliseconds |
$0.0125 + retrieval |
Infrequent access |
| S3 Glacier Deep Archive |
Hours |
$0.00099 + retrieval |
Long-term compliance |
Sample web app monthly cost (1 t3.medium + 100GB S3 + 100GB CloudFront + 1 RDS t3.micro):
| Model |
Total |
Savings |
| On-demand |
$56.17 |
— |
| 1-year Reserved |
$29.68 |
47% |
| Spot (EC2 only) |
$31.37 |
44% |
🎁
Free Tier (12 months)
EC2: 750 hours/month, S3: 5GB, CloudFront: 1TB, RDS: 750 hours
Service Comparison: AWS vs Azure vs GCP
| Service Category |
AWS |
Azure |
GCP |
| Compute (VM) |
EC2 |
Virtual Machines |
Compute Engine |
| Serverless |
Lambda |
Functions |
Cloud Functions |
| Object Storage |
S3 |
Blob Storage |
Cloud Storage |
| Managed K8s |
EKS |
AKS |
GKE |
| Market share (2026) |
32% |
22% |
11% |
Shared Responsibility Model
┌─────────────────────────────────────────────────────────────────────────────┐
│ AWS SHARED RESPONSIBILITY MODEL │
├─────────────────────────────────────────────────────────────────────────────┤
│ CUSTOMER RESPONSIBILITY (Security IN the Cloud) │
│ • Customer data (encryption, access controls) │
│ • Platform and application management │
│ • IAM users, roles, policies │
│ • Operating system patches (on EC2) │
│ • Network firewall configuration │
│ │
│ AWS RESPONSIBILITY (Security OF the Cloud) │
│ • Physical security (data centers, access control) │
│ • Hardware (servers, storage, networking) │
│ • Virtualization layer, hypervisor │
│ • Global infrastructure (regions, AZs, edge) │
│ • Compliance certifications │
└─────────────────────────────────────────────────────────────────────────────┘
Comparison Summary
| Dimension |
AWS |
Azure |
GCP |
| Market share |
32% |
22% |
11% |
| Global regions |
33 |
60+ |
40+ |
| Key strength |
First mover, ecosystem |
Enterprise, hybrid |
Data analytics, AI/ML |
| SLA (compute) |
99.99% |
99.95% |
99.99% |
✅
Conclusion
AWS is the industry standard for cloud computing with 32% market share, 33 global regions, and over 200 services. Understanding AWS is now a core competency for software engineers, not a specialization.
EC2 HIJACK INCIDENT ANALYSIS
I1: Attack Vectors
-
Vector 1: Exposed IAM keys in public repositories – Developer commits AWS access keys to GitHub (public repo). Attackers use automated scanners (truffleHog, gitleaks) to harvest keys within minutes. Real-world: Pagoda (2021) – exposed IAM key led to $8M in fraudulent AWS charges.
-
Vector 2: SSRF to IMDSv1 – Web application vulnerable to Server‑Side Request Forgery allows attacker to query
http://169.254.169.254/latest/meta-iam/security-credentials/ and steal instance role credentials. Real-world: Capital One (2019) – SSRF → IMDSv1 → IAM role → S3 breach (100M+ records).
-
Vector 3: Compromised CI/CD pipeline – Attacker injects malicious code into GitHub Actions or Jenkins, stealing environment variables containing AWS keys. Often via pull request that exfiltrates secrets. Real-world: Codecov (2021) – bash uploader compromised, harvested credentials.
-
Vector 4: Phishing / leaked `.env` files – Developer tricked into sharing credentials via fake login page, or
.env file accidentally committed and not .gitignored. Real-world: Uber (2016) – GitHub leak of AWS keys led to 57M customer records stolen.
-
Vector 5: Overly permissive IAM role on EC2 – Instance role with
AdministratorAccess attached. Attacker compromises the application (RCE) then calls metadata service to retrieve role credentials. Real-world: many cryptomining incidents.
I2: Detection Gaps
| Detection Control |
Should have triggered |
Why it missed |
| AWS CloudTrail |
RunInstances API call from unusual IP / user agent
|
Not enabled, or logs not monitored in real time |
| GuardDuty |
Anomalous EC2 instance launch (high count, unusual region, cryptomining DNS patterns) |
GuardDuty disabled or not covering that region |
| CloudWatch Alarms |
Sudden spike in EC2:RunningInstanceCount or EstimatedCharges
|
No alarm configured for these metrics |
| AWS Budgets |
Daily cost exceeds threshold (e.g., $100) |
Budget alert not set, or threshold too high / not actioned |
| Service Quotas |
Instance limit was 50 or higher – attacker did not hit quota |
Quota not lowered from default (often 100+), so no alert |
| AWS Config |
New EC2 instance type not previously used |
Config recorder disabled, or rule for approved instance types missing |
| Third‑party CSPM |
IaC drift – unexpected resources outside Terraform |
No CSPM agent, or drift detection not configured |
I3: Attack Kill Chain
1. CREDENTIAL THEFT (minutes)
├── Attacker scans GitHub for pattern "AKIA..."
└── Finds exposed keys in victim's public repository
2. VALIDATION & ENUMERATION (seconds)
├── sts.GetCallerIdentity → confirms account ID
├── iam.SimulatePrincipalPolicy → tests if ec2:RunInstances allowed
└── ec2.DescribeRegions → lists all regions, picks us-east-1
3. RESOURCE LAUNCH (minutes)
├── ec2.RunInstances with ImageId=ami-cryptominer
├── User‑data script downloads mining software (XMRig)
├── Launches 50 × t3.medium (2 vCPU, 4GB RAM)
└── Points hashrate to attacker's Monero pool
4. EVASION & PERSISTENCE (hours)
├── Attempts to delete CloudTrail trail (if permissions allow)
├── Uses spot instances (if cheaper) to avoid suspicion
├── Launches in multiple regions to bypass single‑region quota
└── Sets instance termination protection (optional)
5. EXFILTRATION / MONETIZATION (days)
├── Crypto mining runs 24/7 for 72 hours
├── Mining pool sends payouts to anonymous wallet (Monero)
└── Victim receives AWS bill weeks later
I4: Impact Assessment
Financial impact (50 × t3.medium, us-east-1, on‑demand):
- Hourly cost per instance: $0.0416
- Total hourly: 50 × $0.0416 = $2.08/hour
- Duration: 72 hours
- Total compute cost: $2.08 × 72 = $149.76
📌
Note: This is only EC2 compute. Add data transfer (mining pools), EBS volumes (8GB each = 400GB × $0.10/GB‑month ≈ $40), and potential egress. Real‑world bills often exceed $1,000 for 50 instances due to GPUs or longer runtime.
Operational impact: Incident response time: 12+ engineer hours; service degradation if instances collided with production quotas; CloudTrail logs investigation: 2‑3 days.
Security impact: Lateral movement risk; data exposure if same credentials had access to customer databases or S3 buckets; reputation damage (GDPR, CCPA).
Example real‑world: Pagoda – $8M bill; Code Spaces – company went bankrupt after AWS compromise.
I5: Remediation Checklist
Immediate (0‑2 hours)
Short‑term (1‑3 days)
Long‑term (1‑4 weeks)
⚠️
Conclusion
Root cause: Exposed IAM credentials (committed to a public repository) with overly permissive permissions (e.g., ec2:*, iam:*) allowed the attacker to launch 50 instances for cryptomining. Detection failed because CloudTrail was not enabled, GuardDuty not activated, and no budget alerts were configured.
Prevention strategy:
– Never hardcode secrets – use environment variables or Secrets Manager.
– Enforce least privilege IAM – no wildcard actions; use permission boundaries.
– Enable detective controls – CloudTrail, GuardDuty, Config, Budgets.
– Implement automated response – revoke keys, terminate instances, alert on anomalous launches.
– Assume compromise – rotate credentials regularly, limit blast radius with quotas and SCPs.
This incident was entirely preventable. The $150 compute bill is minor compared to the potential data breach or business‑ending damage (see Code Spaces). Treat AWS credentials like nuclear launch codes.
🔐 SECURE API KEY MANAGEMENT FOR GITHUB
S1: Direct Commit Rule
⛔
Verdict: NO
Live API keys are credentials that grant access to social media accounts, billing, and sensitive data. Committing them to GitHub (public or private) exposes them to credential harvesters, automated scanners, and malicious insiders. Even private repositories can be compromised via exposed CI/CD logs, branch misconfigurations, or third‑party integrations. Secrets must never appear in version control.
S2: Secure Pattern
Use: Environment variables + secrets manager (e.g., AWS Secrets Manager, HashiCorp Vault, GitHub Secrets). For local development, load variables from a .env file that is excluded from Git.
// config.js – SECURE VERSION
const dotenv = require('dotenv');
dotenv.config();
const TWITTER_BEARER_TOKEN = process.env.TWITTER_BEARER_TOKEN;
if (!TWITTER_BEARER_TOKEN) {
throw new Error('Missing required env: TWITTER_BEARER_TOKEN');
}
Local development: create .env from .env.example and fill real keys (.env is gitignored).
CI/CD: inject keys via GitHub Actions secrets, GitLab CI variables, or equivalent.
S3: Placeholder Specification
| Service |
Example Placeholder |
File Type |
| Twitter Bearer Token |
YOUR_TWITTER_BEARER_TOKEN |
.env.example |
| Facebook App ID |
YOUR_FACEBOOK_APP_ID |
.env.example |
| Facebook App Secret |
YOUR_FACEBOOK_APP_SECRET |
.env.example |
| LinkedIn Client ID |
YOUR_LINKEDIN_CLIENT_ID |
.env.example |
| Instagram Access Token |
YOUR_INSTAGRAM_ACCESS_TOKEN |
.env.example |
| TikTok Access Key |
YOUR_TIKTOK_ACCESS_KEY |
.env.example |
| Google OAuth Client Secret |
YOUR_GOOGLE_CLIENT_SECRET |
.env.example |
S4: Commit / Ignore Matrix
| File |
Commit? |
Reason |
.env |
NO |
Contains live secrets; must be in .gitignore
|
.env.example |
YES |
Template with placeholders; safe to share |
config/secrets.yml |
NO |
Any file containing real credentials |
src/keys.js |
NO |
Hardcoded keys – refactor to use environment |
docker-compose.yml (with secrets)
|
NO |
If it contains real keys; use env substitution |
.gitignore |
YES |
Must contain .env and secret patterns |
README.md |
YES |
Only if it instructs to copy .env.example
|
.gitignore excerpt:
# Secrets and environment files
.env
.env.local
.env.production
*.pem
*.key
secrets.yml
S5: Remediation Steps
-
Immediate revocation – Revoke the exposed key at the provider (Twitter, Facebook, etc.).
-
Key rotation – Generate a new secret and update all systems that use it (local
.env, CI/CD, production).
-
Purge from Git history – Use
git filter-branch or the BFG Repo-Cleaner to remove the secret from all commits.
-
Force-push – After cleaning, push the rewritten history (coordinate with all collaborators).
-
Notify team – Ensure everyone pulls the new history and discards old branches.
-
Audit logs – Check provider logs for any unauthorized usage between exposure and revocation.
-
Rotate other secrets – If the same commit exposed multiple keys, rotate them all.
Incident response checklist (copy‑paste):
[ ] Revoke exposed key at provider console
[ ] Generate new key and update all environments
[ ] Remove secret from git history (BFG Repo-Cleaner)
[ ] Force-push cleaned branches
[ ] Notify teammates to reclone or reset
[ ] Review provider access logs
[ ] Rotate any other secrets in the same commit
Conclusion
✅
Best practice
Never commit real API keys to any GitHub repository. Use placeholder files (.env.example) as templates, store live secrets in environment variables or a dedicated secrets manager, and always exclude .env via .gitignore. If a key is accidentally committed, revoke it immediately, rotate it, and purge the history. This prevents account takeover, financial abuse, and reputational damage.