Back to Cheat Sheets

🛠️ Insecure System Configuration

OWASP Top 10 CI/CD Security Risks - CICD-SEC-7

HIGH RISK

📋 What Is It?

Insecure System Configuration is the risk that arises when the systems that build and ship software - SCM servers, CI servers, orchestrators, artifact registries, and build runners - are themselves run with insecure settings, left at unsafe defaults, exposed on the network, or allowed to fall behind on patches. The flaw is not in the application code moving through the pipeline; it is in the configuration and posture of the pipeline machinery itself. A CI/CD platform is a peculiarly high-value target: it holds credentials to production, executes arbitrary code by design, and can push artifacts straight into production.

CICD-SEC-7 OWASP Rank
Posture Focus Area
RCE Typical Impact

⚠️ Common Exploits

  • Unpatched Server / Plugins: Known-vulnerable core or plugin matched to a public advisory
  • Exposed Console: Jenkins/GitLab/registry management plane open to the internet
  • Anonymous / Default Auth: "Anyone can do anything" or unchanged admin login
  • Open Script Console: Reachable /script Groovy console = direct RCE
  • Shared / Over-Privileged Runners: Long-lived hosts on flat networks with broad cloud roles
  • Unauthenticated Webhooks: Forged events trigger builds and deploys
  • Cleartext Transport: Plain-HTTP consoles, ignored certificate errors

🔴 Attack Flow

1. Discover exposed console via internet scanners
↓
2. Fingerprint version banner + plugin list
↓
3. Enter via anon access, default creds, or vuln plugin
↓
4. Execute on controller / harvest stored credentials
↓
5. IMPACT: Pivot to prod, tamper builds, add persistence!

❌ Vulnerable Code

# jenkins.yaml (JCasC) - dangerous posture jenkins: authorizationStrategy: "unsecured" ← anyone can do anything securityRealm: "none" ← no real login slaveAgentPort: 50000 ← agent port open to the world remotingSecurity: enabled: false ← agent protocol not secured # /script console reachable by anyone; plugins never pinned or patched. # Served over plain HTTP on :8080, exposed directly to the internet. # nginx - controller open to the world over cleartext server { listen 80; ← plain HTTP, no TLS server_name ci.example.com; ← public DNS name location / { proxy_pass http://127.0.0.1:8080; } } # webhook handler - an unauthenticated pipeline trigger @app.route("/github-webhook/", methods=["POST"]) def hook(): event = request.get_json() trigger_build(event) ← no signature check, no source check return "ok"

✅ Secure Code

# jenkins.yaml (JCasC) - hardened posture jenkins: securityRealm: oic: { clientId: "${JENKINS_OIDC_CLIENT_ID}" } # SSO, MFA upstream authorizationStrategy: roleBased: # anonymous has NOTHING roles: global: - name: "developer" permissions: ["Overall/Read", "Job/Build"] assignments: ["oidc-group-developers"] remotingSecurity: { enabled: true } # secure controller/agent transport # Behind VPN/allow-list, HTTPS only; /script = break-glass admins; plugins pinned. # nginx - TLS-only, allow-listed, private management plane server { listen 80; return 301 https://$host$request_uri; } server { listen 443 ssl; ssl_protocols TLSv1.2 TLSv1.3; location / { allow 10.0.0.0/8; ← corporate/VPN range only deny all; proxy_pass http://127.0.0.1:8080; } } # webhook handler - verify HMAC signature, constant-time, allowed events only expected = "sha256=" + hmac.new(SECRET, raw, hashlib.sha256).hexdigest() if not hmac.compare_digest(sent, expected): abort(401)

✓ Prevention Checklist

  • Patch CI/SCM cores and plugins promptly and continuously
  • Keep consoles/APIs behind VPN or IP allow-list, never public
  • Disable anonymous access; enforce SSO + MFA everywhere
  • Minimise plugins/integrations; pin and vet what remains
  • Restrict script console to audited break-glass admins
  • Turn off debug/verbose modes (e.g. CI_DEBUG_TRACE) in prod
  • Make runners ephemeral, isolated, least-privilege, non-root
  • Never run fork/PR workflows on self-hosted runners
  • Block the cloud metadata endpoint where unused
  • Enforce TLS everywhere with valid, auto-renewed certs
  • Verify webhook HMAC signatures; allow-list the source
  • Harden to a benchmark as config-as-code; detect drift

🔍 Detection & Tools

Hardening & Config-as-Code:

Jenkins Config-as-Code (JCasC) CIS Benchmarks Terraform OpenSSF Scorecard Trivy (misconfig)

Exposure & Runner Isolation:

Ephemeral runners nginx allow-list / VPN Rootless containers no-new-privileges / cap_drop Audit logging

How to Test:

  • Fingerprint version banner: X-Jenkins header on responses
  • List plugins: /pluginManager/api/json?depth=1
  • Check reachability of /script, /systemInfo, /credentials
  • Confirm console is not internet-reachable (external scan)
  • Verify anonymous access grants no read/build/configure
  • Send an unsigned webhook and confirm it is rejected

🌍 Real-World Incident Classes

  • CI-server plugin vulnerability chain: An attacker fingerprints a self-hosted controller's version and outdated plugins, matches a published advisory, and reads files, bypasses auth, or executes code - then harvests stored credentials and pivots. Plugin flaws are one of the most frequently advisory-published classes in the CI ecosystem.
  • Internet-exposed, unauthenticated build console: Automated scanners locate an open console; an attacker reaches a script console or triggers a build, leading to cryptomining on the org's compute or theft of stored secrets.
  • Shared self-hosted runner compromise: A malicious change or poisoned dependency runs on a non-ephemeral shared runner, persists on the host, captures the next job's secrets, and abuses the runner's cloud role and flat network to move toward production.

Note: these are repeatedly-observed patterns, not specific named breaches. Exact rankings and counts vary by report and year - the durable takeaway is that CI/CD systems are common, high-value, easily located targets whose insecure defaults are cheap to exploit.

📌 Quick Tips

  • DO NOT expose the management plane to the internet
  • DO NOT leave anonymous access or default logins on
  • DO NOT share long-lived runners across untrusted jobs
  • DO patch cores and plugins on a cadence
  • DO enforce SSO + MFA and least-privilege roles
  • DO isolate ephemeral, non-root runners
  • DO codify a benchmark and detect drift

📜 Compliance

Related Standards:

  • CIS Benchmarks (Jenkins, GitLab, Docker)
  • NIST 800-53 CM-6 - Configuration Settings
  • SLSA Build L2/L3 - Hardened build platform
  • ISO 27001 A.12.6.1 / A.14.2
  • SOC 2 CC7.1