Command Palette

Search for a command to run...

Hectal
Lab 2.4·Containers & InfrastructureCRITICAL

The pull request that opened the database

A Terraform change to 'debug a connection issue' opens the RDS security group to 0.0.0.0/0 and makes the bucket policy public. The plan looked small, and it was approved.

Weakness
CWE-284 · Improper access control · OWASP A05 Security misconfiguration
Target
the ShopLite Terraform code (Terraform course)
IaC scanning (trivy config, checkov)scanning plans vs codePR annotationsjustified exceptions

Run these techniques only against the lab you own. Using them on systems you don't have permission to test is illegal.

The threat

  1. 01Misconfiguration is the most common cloud breach

    Most cloud data exposures aren't sophisticated exploits: they're a storage bucket made public, a database reachable from the internet, or an overly broad IAM policy, often introduced as a 'temporary' change. Automated internet-wide scanners find open databases and public buckets within hours. With infrastructure as code, these mistakes arrive as diffs in pull requests, where they can be caught automatically.

    infra/security.tf (the change under review)add to filehcl
    resource "aws_vpc_security_group_ingress_rule" "db_debug" {
      security_group_id = aws_security_group.db.id
      cidr_ipv4         = "0.0.0.0/0"          # "temporary, for debugging"
      ip_protocol       = "tcp"
      from_port         = 5432
      to_port           = 5432
    }

What's at risk

  • The production database's login port reachable from the entire internet, relying on the password alone.

Detect

  1. 01Scan the Terraform in the PR

    terminal
    $ docker run --rm -v "$PWD/infra:/src" aquasec/trivy:0.63.0 config --severity HIGH,CRITICAL /src
    ── output ──
    security.tf (terraform)
    Tests: 112 (SUCCESSES: 111, FAILURES: 1)
    Failures: 1 (HIGH: 0, CRITICAL: 1)
     
    AVD-AWS-0107 (CRITICAL): Security group rule allows ingress from public internet.
    ════════════════════════════════════════
    security.tf:61-67
    ────────────────────────────────────────
    63 │ cidr_ipv4 = "0.0.0.0/0"
  2. 02Or checkov, with a different rule set

    Running two scanners catches more, since their rule sets differ. checkov -d infra --compact reports the same public-ingress finding under its own rule ID. Pick one scanner as the blocking gate and keep the other advisory, so developers aren't asked to satisfy two tools for the same finding.

Defend

  1. 01Fix the need, not just the rule

    The engineer needed to reach the database to debug. The Session Manager tunnel from the Terraform course (Mission 4.1) gives exactly that, with no open ports and full audit logging. Remove the rule; document the tunnel in the runbook.

    Vulnerable

    infra/security.tfadd to filehcl
    cidr_ipv4 = "0.0.0.0/0"   # "temporary, for debugging"

    Hardened

    runbook: connecting to the databasewhole filebash
    aws ssm start-session --target <probe-instance> \
      --document-name AWS-StartPortForwardingSessionToRemoteHost \
      --parameters "host=<db-endpoint>,portNumber=5432,localPortNumber=15432"
  2. 02Make the scanner a required PR check

    Run it on every PR that touches infra/ or modules/, upload results as SARIF so findings appear inline on the diff, and mark the check required in branch protection. Accepted risks are suppressed in code with a reason, so the decision is reviewed and visible.

    Hardened

    .github/workflows/iac-scan.ymlwhole fileyaml
    on:
      pull_request:
        paths: ["infra/**", "modules/**"]
    permissions: { contents: read, security-events: write }
    jobs:
      trivy-config:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@<sha> # v4
          - uses: aquasecurity/trivy-action@<sha> # 0.32.0
            with:
              scan-type: config
              severity: HIGH,CRITICAL
              exit-code: "1"
              format: sarif
              output: trivy.sarif
          - uses: github/codeql-action/upload-sarif@<sha> # v3
            if: always()
            with: { sarif_file: trivy.sarif }

Verify

  1. 01Scanner passes; the policy gate on the plan agrees

    The static scan is clean, and the OPA plan policy from the Terraform course (Mission 7.3) would also have denied the rule, since it checks for public ingress in the PLANNED values. Two independent layers: code scanning catches it early; plan policy catches values that only resolve at plan time.

    terminal
    $ docker run --rm -v "$PWD/infra:/src" aquasec/trivy:0.63.0 config -q --severity HIGH,CRITICAL /src
    ── output ──
    (no findings)

The concepts

Shift left, and keep the right

Scanning IaC in pull requests catches misconfigurations before they exist. It can't catch changes made outside code, such as console edits or other tools. So keep runtime detection too: AWS Config rules, Security Hub, and drift detection (Terraform course, Mission 7.4). Prevention in the PR, detection in the account.

Your turn

01

How do you suppress a trivy config finding for one resource with a reason?

Interview questions

01

How do you prevent insecure infrastructure changes?

0/4 · 0%