CVE-2026-23742: Skipper Inline Lua Filters Enable Unauthorized File Access and Secret Disclosure

CVE: CVE-2026-23742
Alias: Skipper inline Lua filter vulnerability
CVSS v3.1 Score: 8.8 (High)
Severity: High
Exploitability:

  • Attack Vector: Network
  • Privileges Required: Low (ability to define filters)
  • User Interaction: None
  • Exploit Status: Conceptually simple to abuse; no widely distributed exploit code in major feeds at this moment

What the Vulnerability Is

Skipper is a widely used HTTP router and reverse proxy that helps route traffic inside cloud environments — especially Kubernetes.

Some Skipper deployments allow Lua scripts embedded directly (“inline”) in route definitions or Ingress objects. Prior to version 0.23.0, the default setting included -lua-sources=inline,file, meaning Skipper would accept Lua code from more places than just trusted files.

Here’s the crux of the problem:

  • If an attacker (or low-privileged user) can create or update a route or Ingress definition that Skipper reads, they can include their own Lua script.
  • That Lua code runs inside Skipper’s process with whatever privileges Skipper has.
  • A malicious script can open arbitrary files Skipper has access to — including configuration, service tokens, or secrets mounted into the container.
  • If the attacker can also read Skipper’s logs (which many environments allow), the script can dump file contents into logs, exposing credentials or sensitive data.

This turns a flexible runtime scripting feature into a local file access / secret disclosure vulnerability by design.


How Exploitation Works

Typical Exploitation Path

  1. Access control gap: An attacker has rights to define or edit certain Skipper route objects (e.g., Kubernetes Ingress annotations).
  2. Inline Lua injection: Attacker writes a Lua filter that uses basic file I/O functions (io.open, etc.) to read sensitive files.
  3. Triggering execution: The malicious filter is deployed; Skipper loads and runs it.
  4. Data exfiltration: The script prints file contents to stdout or stderr — often captured in logs — or reflects it back in an HTTP response if possible.
  5. Harvesting secrets: The attacker fetches logs or crafted responses to collect file contents.

This is a two-stage exploitation: ability to define filters and ability to read Skipper logs or responses. The more privileged the attacker is in the configuration system, the easier this abuse becomes.


How to Detect Exploitation

Detecting misuse of this vulnerability involves monitoring two main areas:

  1. Unauthorized filter creation / modification
  2. Suspicious behavior in logs / traffic that indicates file reads or exfiltration

Below are detection strategies and Splunk rules tailored for operational teams.


Log Sources You Need

Log SourceWhy It Matters
Skipper runtime logsShows filter loading, errors, and script execution output
Kubernetes audit logsShows who created or modified route/Ingress objects
API server logsTrusted source of object mutations and identities
Application access logsCan show exfiltration payloads in responses
Container logsUseful if Skipper writes to stdout/stderr

Splunk Detection Rules

1) Detect Ingress/Route Definitions with Inline Lua

index=kube_audit_logs 
(resource="ingresses" OR resource="routes")
(requestBody="*lua*" OR requestBody="*filter*")
| stats count by user, namespace, resource, name, requestBody
| where count > 0

This rule catches any Kubernetes object creation or update that contains lua in its definition.


2) Skipper Logs — Inline Lua Filter Execution

index=skipper_logs
("inline lua" OR "lua filter" OR "loading lua")
| stats count by host, message

This surfaces instances where Skipper acknowledges loading or running Lua code.


3) Anomalous Log Output (Possible File Dumping)

index=skipper_logs
| rex field=_raw "(\/etc\/|\/var\/run\/|token)"
| search token OR passwd OR shadow
| stats count by host, _raw

This identifies log entries containing paths or sensitive tokens — common indicators of file access.


4) Unusual HTTP Responses (Potential Secret Exfil)

index=access_logs status=200
| regex _raw="([A-Za-z0-9+/]{50,}=*)" 
| stats count by client_ip, uri

Long base64-like strings in responses can signal exfiltrated file contents.


Indicators of Exploitation

These are patterns worth alerting on or investigating:

  • Creation/modification of routes containing inline Lua code where such behavior isn’t normal.
  • Skipper logging unusual errors or messages referencing filesystem paths.
  • Unexpected HTTP responses with long encoded blobs (base64 or similar).
  • New or unusual access to secret file paths in logs (/var/run/secrets/..., /etc/passwd, etc.).
  • Config changes by identities that don’t normally manage routing.

Mitigation & Hardening

Even before upgrading, you can significantly reduce risk:

Immediate

  • Disable inline Lua filters: Configure Skipper with restricted Lua sources (e.g., only file-based scripts).
  • Limit who can create filters: Tighten RBAC for Kubernetes Ingress/route resources.
  • Run Skipper with least privilege: Don’t grant it access to secret paths unnecessarily.
  • Audit recent Ingress configurations for suspicious lua entries.

Long Term

  • Upgrade Skipper to v0.23.0 or later — this release changes defaults to prevent untrusted inline Lua code execution.
    👉 https://github.com/zalando/skipper/releases/tag/v0.23.0
  • Implement consistent logging and alerting around config changes and runtime behavior.
  • Regularly rotate secrets to reduce exposure risk if a secret could have been read.

Proof-of-Concept / Payload Patterns (For Educational Use Only)

Here’s a conceptual example of what an attacker might try — shared strictly for defenders to test detection coverage:

  • Inline Lua payload snippet (illustrative only; do not run in production):
function request(ctx, params)
  local f = io.open('/etc/passwd', 'r')
  if f then
    local content = f:read('*all')
    f:close()
    ngx.log(ngx.ERR, "[PWNED] " .. content)
  end
end

This simply reads a file and writes its contents to error logs where a monitoring solution might catch it.


Final Takeaway

At its core, CVE-2026-23742 is about giving too much power to inline scripting in a critical network component. Where scripting should be controlled and trusted, the old defaults allowed less-trusted actors to run code inside Skipper — and read anything that Skipper itself had access to.

That’s serious because:

  • It can expose secrets.
  • It doesn’t require complex exploit tools.
  • It happens inside the routing layer, often overlooked.

Detection focuses on:

  1. Watch for unauthorized filter changes.
  2. Monitor Skipper logs for script execution and file dumps.
  3. Alert on suspicious response behavior.

Fix it by upgrading to v0.23.0 and tightening access around who can define filters.


Aegiron

Backed by 11+ years in cybersecurity and incident response, we decode the latest threats shaping today’s digital battlefield. This blog cuts through the noise with clear insights on vulnerabilities, emerging exploits, and the cyber news defenders can’t afford to miss.