Skip to content

CVE-2026-42091: Verified Repro With Script Download

CVE-2026-42091: goshs: PUT upload accepts cross-origin requests without CSRF token

CVE-2026-42091 is verified against github.com/patrickhener/goshs · go. Affected versions: <= v2.0.1 (commit f5671ea). Fixed in v2.0.2. Vulnerability class: CSRF. This medium reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00158.

REPRO-2026-00158 github.com/patrickhener/goshs · go CSRF May 23, 2026 CVE entry ↗ .txt
Severity
MEDIUM
CVSS
6.5
Reproduced in
35m 17s
Tool calls
171
Spend
$1.63
01 · Overview

What Is CVE-2026-42091?

CVE-2026-42091 (GHSA-rhf7-wvw3-vjvm) is a medium-severity Cross-Site Request Forgery vulnerability (CWE-352) in goshs, a Go-based HTTP file server, in which the PUT upload endpoint accepts cross-origin requests without a CSRF token. Pruva reproduced it (reproduction REPRO-2026-00158).

02 · Severity & CVSS

CVE-2026-42091 Severity & CVSS Score

CVE-2026-42091 is rated medium severity, with a CVSS base score of 6.5 out of 10.

MEDIUM threat level
6.5 / 10 CVSS base
Weakness CWE-352 (Cross-Site Request Forgery) — Cross-Site Request Forgery (CSRF)

Medium — meaningful risk under specific conditions. Schedule a fix in the normal cycle.

03 · Affected Versions

Affected github.com/patrickhener/goshs Versions

github.com/patrickhener/goshs · go versions <= v2.0.1 (commit f5671ea) are affected.

How to Reproduce CVE-2026-42091

$ pruva-verify REPRO-2026-00158
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00158/artifacts/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-42091

Reproduced by Pruva's autonomous agents — 171 tool calls over 35 min. Full root-cause analysis and the complete transcript are below.

How the agent worked 636 events · 171 tool calls · 35 min
35 minDuration
171Tool calls
153Reasoning steps
636Events
3Dead-ends
Agent activity over 35 min
Support
16
Repro
206
Variant
409
0:0035:17

Root Cause and Exploit Chain for CVE-2026-42091

Summary

goshs (a Go-based HTTP file server CLI) versions ≤ v2.0.1 are vulnerable to Cross-Site Request Forgery (CSRF) on the PUT upload endpoint. While the POST upload handler enforced CSRF token validation via checkCSRF(), the put() handler in httpserver/updown.go omitted this check entirely. Combined with permissive CORS headers (Access-Control-Allow-Origin: *), a malicious cross-origin webpage can silently issue an HTTP PUT and write arbitrary files to any reachable goshs instance.

Impact

  • Package: github.com/patrickhener/goshs
  • Affected versions: ≤ v2.0.1
  • Fixed version: v2.0.2
  • CWE: CWE-352 (Cross-Site Request Forgery)
  • Severity: Medium (CVSS 3.1 base 6.5)
  • Risk: Any website visited by a user whose browser can reach a goshs upload server (loopback, LAN, VPN, etc.) can upload arbitrary files without user consent.

Root Cause

The put() handler in httpserver/updown.go did not call fs.checkCSRF(w, req) before processing the request. The checkCSRF() function (present in httpserver/handler.go) validates the X-CSRF-Token header, absence of Origin/Referer (non-browser clients), or same-origin requests. Because put() skipped this validation, a browser-initiated cross-origin PUT request—bearing an arbitrary Origin header but no valid token—was accepted and the file was written to disk.

The fix commit 0e715b94e10c3d1aa552276000f15f104dee2f32 adds the missing checkCSRF() call at the top of put().

Reproduction Steps

The reproduction is fully automated by repro/reproduction_steps.sh. It performs the following:

  1. Clones the goshs repository (or reuses an existing clone).
  2. Builds the vulnerable binary at tag v2.0.1 (goshs_v2.0.1).
  3. Builds the fixed binary at tag v2.0.2 (goshs_v2.0.2).
  4. Starts each binary in a separate scratch upload directory with upload enabled.
  5. Sends a cross-origin-style PUT request (curl -X PUT -H "Origin: http://evil.com" --data-binary 'pwned' http://localhost:<port>/pwned.txt).
  6. Captures the HTTP response status and checks whether pwned.txt was created.

Expected evidence of reproduction:

  • v2.0.1 (vulnerable): HTTP 200 OK and pwned.txt is created in the upload directory.
  • v2.0.2 (fixed): HTTP 403 Forbidden and pwned.txt is not created.

Evidence

All logs are written to logs/:

  • logs/vuln.log — goshs v2.0.1 server output.
  • logs/vuln_result.json — captured HTTP status (200), response body, and file_created: true.
  • logs/fixed.log — goshs v2.0.2 server output.
  • logs/fixed_result.json — captured HTTP status (403), response body (Forbidden), and file_created: false.

Excerpt from logs/vuln_result.json:

{
  "version": "vuln",
  "http_status": "200",
  "response_body": "",
  "file_created": true,
  "upload_dir": ".../logs/upload_vuln"
}

Excerpt from logs/fixed_result.json:

{
  "version": "fixed",
  "http_status": "403",
  "response_body": "Forbidden",
  "file_created": false,
  "upload_dir": ".../logs/upload_fixed"
}

Environment:

  • Go version used for build: go1.24.7 (v2.0.1) / go1.25.0 (v2.0.2)
  • OS: Linux (containerized)
  • Network: localhost (127.0.0.1)

Recommendations / Next Steps

  1. Immediate fix: Upgrade to goshs v2.0.2 or later, which enforces checkCSRF() on every mutating handler (PUT, POST, DELETE).
  2. Defense in depth: If running goshs on a publicly reachable interface, pair it with --basic-auth (-b user:pass). When basic auth is configured, the CORS preflight already fails in browsers, providing an additional layer of protection.
  3. Regression testing: Any future change to upload handlers should be accompanied by a test that sends a cross-origin request with a mismatched Origin header and asserts 403 Forbidden.

Additional Notes

  • Idempotency: The reproduction script was executed twice consecutively and produced identical results both times.
  • Edge cases: The script simulates a browser cross-origin request by explicitly sending an Origin header. Without this header, curl requests are treated as non-browser clients and are allowed by design (see checkCSRF logic). The vulnerability specifically affects browser-based CSRF attacks.
  • Limitations: The reproduction does not require a real browser or a second origin; the malicious cross-origin behavior is accurately modeled with curl and the Origin header.

CVE-2026-42091 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:000:58
0:00
session startedaccounts/fireworks/models/kimi-k2p6 · cve-2026-42091 · cve-2026
0:06
0:08
web search
0:11
0:13
0:35
0:35
extract_facts
no facts extracted
0:36
0:36
0:36
supportrepro
0:39
0:41
0:41
0:41
0:43
0:43
0:43
0:43
0:45
0:45
0:51
$cd /tmp && git clone --depth=100 https://github.com/patrickhener/goshs.git 2>&1 | tail -5
5.4s
{"cwd":"/root/.pruva/runs/cve-2026-42091_20260523-061423","duration_ms":5435,"exit_code":0,"stderr":"","stdout":"Cloning into 'goshs'...\nUpdating files:  28% (63/225)\rUpdating files:  29% (66/225)\rUpdating files:  30% (68/225)\rUpdating files:  31% (70/225)\rUpdating files:  32% (72/225)\rUpdating files:  33% (75/225)\rUpdating files:  34% (77/225)\rUpdating files:  35% (79/225)\rUpdating files:  36% (81/225)\rUpdating files:  37% (84/225)\rUpdating files:  38% (86/225)\rUpdating files:  39% (88/225)\rUpdating files:  40% (90/225)\rUpdating files:  41% (93/225)\rUpdating files:  42% (95/225)\rUpdating files:  43% (97/225)\rUpdating files:  44% (99/225)\rUpdating files:  45% (102/225)\rUpdating files:  46% (104/225)\rUpdating files:  47% (106/225)\rUpdating files:  48% (108/225)\rUpdating files:  49% (111/225)\rUpdating files:  50% (113/225)\rUpdating files:  51% (115/225)\rUpdating files:  52% (117/225)\rUpdating files:  53% (120/225)\rUpdating files:  54% (122/225)\rUpdating files:  55% (124/225)\rUpdating files:  56% (126/225)\rUpdating files:  57% (129/225)\rUpdating files:  58% (131/225)\rUpdating files:  59% (133/225)\rUpdating files:  60% (135/225)\rUpdating files:  61% (1… [truncated]
0:58

Artifacts and Evidence for CVE-2026-42091

Scripts, logs, diffs, and output captured during the reproduction.

No artifacts available

08 · How to Fix

How to Fix CVE-2026-42091

Upgrade github.com/patrickhener/goshs · go to v2.0.2 or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-42091 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-42091

How does the CVE-2026-42091 CSRF attack work?

A victim who can reach a goshs instance (loopback, LAN, VPN, etc.) visits a malicious cross-origin webpage. That page silently issues an HTTP PUT to the goshs server; because put() never calls checkCSRF() and CORS is permissive, the browser's cross-origin request is accepted without any token, and the attacker's file content is written to disk on the goshs server.

Which goshs versions are affected by CVE-2026-42091, and where is it fixed?

goshs (github.com/patrickhener/goshs) versions <= v2.0.1 (commit f5671ea) are affected. It is fixed in v2.0.2, which adds the missing checkCSRF() call to the PUT path.

How severe is CVE-2026-42091?

It is rated medium severity: any website visited by a user whose browser can reach a goshs upload server can write arbitrary files without user consent, but exploitation requires the goshs instance to be network-reachable from the victim's browser.

How can I reproduce CVE-2026-42091?

Download the verified script from this page and run it in an isolated environment against goshs <= v2.0.1 with upload enabled. It simulates a cross-origin browser PUT request with an arbitrary Origin header and no CSRF token, and confirms the file is written on the vulnerable build while v2.0.2 rejects the same request.
11 · References

References for CVE-2026-42091

Authoritative sources for CVE-2026-42091 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.