A02 Security Misconfiguration
Defaults are built for convenience, not for the internet. A debug flag, an open bucket, a verbose error or a default password turns correct code into an incident.
What it is
is any gap between how a system is set up and how it should be: unnecessary features enabled, default accounts left in place, debug mode in production, missing security headers, permissive cloud permissions, or stack traces shown to users.
It is A02 in :2025 because it is everywhere and cheap to find: attackers scan the whole internet for the same few mistakes.
How the attack works
- A framework left in debug mode exposes an interactive console or full stack traces with file paths and secrets.
- A storage bucket, database or admin panel is reachable from the internet with default or no credentials.
- Directory listing or a leftover /.git, /.env or backup file leaks source and keys.
- XML parsers with external entities enabled let a crafted document read local files.
- Permissive (a wildcard origin with credentials) lets any website call the API as the victim.
Vulnerable configuration
Three common shapes: debug on, wildcard CORS with credentials, and a public container exposing a database.
app = Flask(__name__)
app.config["DEBUG"] = True # interactive debugger reachable in production
CORS(app, origins="*", supports_credentials=True)services:
db:
image: postgres:latest
ports:
- "5432:5432" # published on every interface
environment:
POSTGRES_PASSWORD: postgresresource "aws_s3_bucket_public_access_block" "assets" {
bucket = aws_s3_bucket.assets.id
block_public_acls = false
block_public_policy = false
}The fix
Make the secure setting the default and build it once: a hardened base image, a reviewed configuration module, and the same settings in every environment, applied from code. Remove what you do not use.
app = Flask(__name__)
app.config["DEBUG"] = os.environ.get("APP_ENV") == "development"
CORS(app, origins=["https://app.example.com"], supports_credentials=True)
@app.after_request
def set_headers(resp):
resp.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains"
resp.headers["X-Content-Type-Options"] = "nosniff"
resp.headers["Content-Security-Policy"] = "default-src 'self'"
return respservices:
db:
image: postgres:16
expose:
- "5432" # reachable only by other services on the network
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_passwordresource "aws_s3_bucket_public_access_block" "assets" {
bucket = aws_s3_bucket.assets.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}Prove the fix
Misconfiguration is verified by scanning, not by reading code. Run a config scanner in CI against and images, and run a small check against the deployed app. The test fails the build when a safe default regresses.
# 1. infrastructure code: fail on misconfigured resources
checkov -d infra/ --quiet --compact
# 2. container image: fail on HIGH/CRITICAL findings
trivy image --exit-code 1 --severity HIGH,CRITICAL registry.example.com/app:$GIT_SHA
# 3. deployed app: required headers must be present
curl -sI https://staging.example.com | grep -qi '^strict-transport-security:' || exit 1
curl -sI https://staging.example.com | grep -qi '^content-security-policy:' || exit 1def test_debug_is_off_in_production(monkeypatch):
monkeypatch.setenv("APP_ENV", "production")
assert create_app().config["DEBUG"] is False
def test_cors_does_not_allow_any_origin(client):
resp = client.options("/api/me", headers={"Origin": "https://evil.example"})
assert resp.headers.get("Access-Control-Allow-Origin") != "*"Checklist
- One repeatable, automated hardening process for every environment; no hand-tuned servers.
- Remove unused features, sample apps, default accounts, and open ports.
- Send the security headers that apply (HSTS, CSP, X-Content-Type-Options, frame protection).
- Show generic errors to users; send details to logs, not to the response.
- Review cloud permissions and storage exposure continuously, not once.
- Treat configuration as code: reviewed, versioned, scanned.
connections on the map
- A02 Security Misconfigurationincludes the pipeline ofA03 Software Supply Chain Failures
updated on 14/10/2026 · sources to go deeper · report an error
in other domains
- CSPM - cloud posturecloudseccontinuous verification of configuration
- Secure infrastructure as codesecengsecure configuration starts in infrastructure code
test what you learned
Loading questions…