What's the vulnerability?

Arbitrary code execution through lua filters.

The default skipper configuration before v0.23 was -lua-sources=inline,file. The problem starts if untrusted users can create lua filters, because of -lua-sources=inline , for example through a Kubernetes Ingress resource. The configuration inline allows these user to create a script that is able to read the filesystem accessible to the skipper process and if the user has access to read the logs they an read skipper secrets.

Kubernetes example (vulnerability is not limited to Kubernetes)

function request(ctx, params)
  local file = io.open('/var/run/secrets/kubernetes.io/serviceaccount/token', 'r')
  if file then
    local token = file:read('*all')
    file:close()
    error('[EXFIL] ' .. token)  -- Exfiltrate via error logs
  end
end

Root Cause Analysis

## Summary
Skipper releases prior to v0.23.0 enable inline Lua filters by default (`-lua-sources=inline,file`). Any user able to submit a Lua filter (for example through an Ingress resource) can run arbitrary Lua code inside the Skipper process and access the local filesystem. Our reproduction shows that a crafted inline Lua script can read `/etc/hostname` and leak its contents through Skipper’s logs.

## Impact
- **Component:** `github.com/zalando/skipper` proxy binary
- **Affected Versions:** all versions before v0.23.0 (where Lua is enabled by default)
- **Risk:** High (CVSS 8.8) – attackers can execute arbitrary Lua code, read sensitive files (tokens, secrets), and exfiltrate data via logs or upstream responses. If the Skipper process holds credentials or tokens, they can be stolen.

## Root Cause
Skipper allowed inline Lua scripts to be embedded directly into route definitions and executed without sandboxing. When `-lua-sources` includes `inline` (default before v0.23.0), user-controlled Lua scripts run in the Skipper process with access to the standard Lua IO library. This enables arbitrary file reads/writes and system interaction. The issue was mitigated in v0.23.0 by disabling Lua filters by default (commit `0b52894570773b29e2f3c571b94b4211ef8fa714`).

## Reproduction Steps
1. Run `repro/reproduction_steps.sh` from the workspace root.
2. The script downloads Skipper v0.22.0, writes a malicious inline Lua route that reads `/etc/hostname`, starts Skipper with the route, and triggers it via `curl`.
3. Successful reproduction is evidenced by the Skipper log entry containing `[EXFIL] <hostname>` and the summary message printed by the script. Logs are stored under `logs/`.

## Evidence
- **Logs:**
  - `logs/reproduction.log` – full script run output
  - `logs/skipper_inline.log` – Skipper process logs
  - `logs/exfiltration.txt` – filtered `[EXFIL]` line showing leaked hostname
  - `logs/request.log` – HTTP status (404) from trigger request
- **Key Excerpt:** `logs/exfiltration.txt` contains `Error calling request ... [EXFIL] <hostname>` proving filesystem data leakage.
- **Environment:** `uname -a` → `Linux runsc 4.4.0 ... x86_64 GNU/Linux`

## Recommendations / Next Steps
- Upgrade Skipper to v0.23.0 or later, where Lua filters are disabled by default.
- If Lua scripts are required, explicitly limit `-lua-sources=file` and ensure only trusted scripts are deployed on the filesystem.
- Harden Lua execution by removing IO modules or running in a restricted sandbox, and add automated tests to ensure inline Lua stays disabled unless explicitly allowed.

## Additional Notes
- The reproduction script is idempotent: it reuses downloaded artifacts, stops Skipper between runs, and was executed successfully twice in a row.
- The exploit demonstrates read access; write/execute primitives are also possible via Lua IO APIs under the same configuration.
One Command

Verify with pruva-verify

Run the Pruva CLI to automatically fetch and execute the reproduction script.

pruva-verify REPRO-2026-00066
or pruva-verify GHSA-cc8m-98fm-rc9g
Install: curl -fsSL https://pruva.dev/install.sh | sh

Or Run Manually

1

Download the script

curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00066/artifacts/reproduction_steps.sh
2

Make executable

chmod +x reproduction_steps.sh
3

Run the script

./reproduction_steps.sh
Run in a VM, container, or disposable environment. This exploits a real vulnerability.

How Pruva Reproduced This

Watch the AI agent's step-by-step process.

Loading session...

Artifacts

No artifacts available