Skip to content

CVE-2014-6271 — Shellshock

Bash supported exporting functions through environment variables. The export syntax — () { …; } — was parsed by any newly-spawned bash process on import. A trailing semicolon let the imported “function” body include arbitrary commands. Any process boundary that turned untrusted input into a bash environment variable became RCE. The classic target was mod_cgi: HTTP headers became env vars; bash was the CGI interpreter; game over. The first patch was incomplete; the durable fix runs through six follow-up CVEs.

Affected versions

  • Bash 1.14 through 4.3 (with various patch levels) — vulnerable.
  • The fix shipped in patch levels: bash-3.2.53, bash-4.1.14, bash-4.2.50, bash-4.3.27, plus follow-up patches for the five sibling CVEs.
  • Modern Bash (5.x) — clean.

Indicator-of-exposure

Detection is simple but the surface is wide:

# The classic detection one-liner (CVE-2014-6271):
env x='() { :; }; echo VULNERABLE' bash -c 'true'

# The follow-up (CVE-2014-7169):
env X='() { (a)=>\\' bash -c 'echo date'; cat echo

If the first prints VULNERABLE or the second produces a file named echo containing the date, the bash on this host has not been fully patched.

The exposure that matters is any process boundary that maps untrusted input into a Bash environment:

  • Apache mod_cgi / mod_cgid invoking a #!/bin/bash CGI script.
  • DHCP clients that pass server-supplied options into a Bash hook script.
  • Forced-command SSH configs that run a Bash wrapper.
  • Setuid wrappers that drop into Bash.
  • Container entrypoints that re-exec Bash with attacker- controlled env.

Remediation strategy

  • Upgrade Bash to a current 5.x release, or to the patch level that includes the fix for all of the Shellshock-family CVEs (-6271, -7169, -6277, -6278, -7186, -7187). Do not stop at the first one.
  • Audit every CGI / DHCP-hook / setuid wrapper / SSH forced-command surface for use of Bash. Replace #!/bin/bash with #!/bin/dash (or /bin/sh if Debian-family) where the script doesn’t need Bash features.
  • Disable mod_cgi and mod_cgid in any web server that doesn’t need them.
  • Re-audit the system as a whole. Shellshock exposure on a host today implies a multi-year patching gap; the incident response is broader than one CVE.

The prompt

You are remediating Shellshock and its sibling CVEs on this
host or system image. Output exactly one of:

- A PR / change request upgrading bash and tightening the
  exposed CGI / DHCP / SSH-hook surface, plus an IR
  checklist for the operator.
- A TRIAGE.md if the host's patching gap is broader than
  this CVE family.

## Step 0 — Detect

1. Read bash version: `bash --version`.
2. Run all six Shellshock detection one-liners (or pull a
   detection script from a trusted source). Confirm none
   print the canary string.
3. Identify Bash-using boundaries:
   - `find / -name '*.cgi' -exec head -1 {} \\; | grep bash`
   - DHCP hook scripts under `/etc/dhcp` /
     `/etc/NetworkManager/dispatcher.d`.
   - SSH `authorized_keys` `command=` forced commands.
   - Container entrypoints that re-exec Bash.

## Step 1 — Upgrade Bash

1. `apt upgrade bash` / `dnf upgrade bash` to the
   distro's current packaged version.
2. Re-run all six detection one-liners. None should fire.

## Step 2 — Tighten exposed surfaces

For every Bash-using boundary identified in Step 0:

- **CGI scripts:** if the script doesn't need Bash features
  (associative arrays, `[[`-tests, process substitution),
  switch the shebang to `/bin/dash` or `/bin/sh`. If it
  does need Bash, keep Bash but document the exposure.
- **`mod_cgi` / `mod_cgid`:** disable in `httpd.conf` /
  `apache2.conf` if the application can serve via FastCGI,
  PHP-FPM, or a modern WSGI / ASGI stack instead.
- **DHCP hooks:** review for shell injection on
  server-controlled fields. The agent doesn't auto-rewrite
  these — flag for triage.
- **SSH forced commands:** audit the wrapper script;
  prefer a non-shell binary or a tightly-controlled allowlist.

## Step 3 — IR checklist (when patching gap is broader)

The TRIAGE.md must include:

- Confirm host distro is supported and currently patched.
- Rotate any credentials that ran through the exposed
  surface (CGI auth tokens, DHCP-distributed secrets).
- Audit web logs and DHCP logs for known Shellshock
  exploitation patterns: `User-Agent: () { :; };`,
  `Referer: () { :; };`, etc.
- Schedule a comprehensive runtime upgrade.

## Stop conditions

- Distro is end-of-life and no patched bash is available.
  Triage with a recommendation to migrate.
- A CGI script genuinely depends on Bash and the migration
  to FastCGI/WSGI is non-trivial. Flag and triage.
- The host's auth log shows unexplained sessions during the
  exposure window — this is incident response, not
  routine remediation.

## Scope

- Do not rewrite CGI scripts beyond the shebang change.
- Do not disable `mod_cgi` if a legitimate application
  depends on it; flag for triage instead.
- Do not bundle unrelated CVE fixes.

Verification — what the reviewer looks for

  • All six Shellshock-family detection one-liners pass after the upgrade.
  • The Bash-using boundary list in the PR body is complete and accurate (re-grep to confirm).
  • For surfaces where Bash was replaced with dash / sh, the script’s tests still pass — Bashisms ([[, ==, array syntax) are the common breakers.
  • The reviewer does not assume the absence of mod_cgi is the same as the absence of all Bash-CGI surfaces.

Watch for

  • Single-CVE patching. Many vendor advisories shipped a fix for -6271 days before -7169. A host patched against only the first is still exploitable. Test all six.
  • Bash on Alpine. Alpine’s default shell is ash, but containers that explicitly install bash inherit the same exposure. Audit Dockerfiles.
  • Container entrypoints. A CMD ["/bin/bash"] with attacker-controlled env (e.g., from an upstream input) re-creates the same surface inside a container. The generic remediation is to replace the entrypoint with a non-shell binary.
  • OS images that aren’t actively patched. Shellshock exposure on a host in 2026 is a tip-of-the-iceberg signal. The recipe says so; don’t treat the bash bump as the end of the conversation.
  • Proxies and load-balancers. Some appliances embed older Bash. The same shape applies; the fix path is the appliance vendor’s, not the host’s.

Related