GHSA-3WHC-QVHV-XQJP

Vulnerability from github – Published: 2026-07-01 21:56 – Updated: 2026-07-01 21:56
VLAI
Summary
goshs: WebDAV listener ignores --read-only, --upload-only, and --no-delete mode flags
Details

WebDAV listener ignores --read-only, --upload-only, and --no-delete mode flags

Ecosystem: Go Package: goshs.de/goshs/v2 (github.com/patrickhener/goshs) Affected: <= v2.0.9 (every release that ships the WebDAV handler)

Summary

When goshs is launched with WebDAV enabled (-w), the mode-restriction flags --read-only, --upload-only, and --no-delete are enforced only on the primary HTTP port. The WebDAV port is wired straight to golang.org/x/net/webdav.Handler with no equivalent guard, so an authenticated WebDAV client can PUT, DELETE, MKCOL, MOVE, and COPY despite the operator's stated intent.

Details

httpserver/server.go:207-238 — the WebDAV mux registers only IPWhitelistMiddleware, ServerHeaderMiddleware, and optionally BasicAuthMiddleware. There is no fs.ReadOnly || fs.UploadOnly || fs.NoDelete check on the WebDAV path. The HTTP mux in the same file (lines 134-204) does check these flags on every state-changing route.

Proof of concept

mkdir -p /tmp/r && echo secret > /tmp/r/x.txt
goshs -p 18000 -wp 18001 -w -ro -d /tmp/r -b admin:pw &

curl -u admin:pw -X PUT    http://localhost:18000/y.txt --data x   # 403  (HTTP enforces -ro)
curl -u admin:pw -X PUT    http://localhost:18001/y.txt --data x   # 201  (WebDAV writes anyway)
curl -u admin:pw -X DELETE http://localhost:18001/x.txt            # 204  (WebDAV deletes anyway)
curl -u admin:pw -X MKCOL  http://localhost:18001/pwned/           # 201  (WebDAV creates dir)

Impact

  • Integrity — --read-only and --no-delete are silently downgraded to "no protection" on the WebDAV port. Any WebDAV client (curl, cadaver, Windows Explorer, Finder) can overwrite/delete files.
  • Confidentiality — --upload-only is also bypassed: WebDAV GET/PROPFIND still return file contents.
  • Trust — operators using goshs -w -ro -d /srv/case-files -b reviewer:pw to deliver engagement artifacts believe the directory is immutable. It isn't.

Suggested fix

Add a small http.HandlerFunc in front of wdHandler that maps WebDAV verbs to the existing mode flags:

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

Add regression tests in integration/functions.go covering each mode flag × each WebDAV verb.

Reporter: Nishant Verma. Reproduced live against goshs v2.0.9 (commit 8fc1e91) on 2026-05-27.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 2.0.9"
      },
      "package": {
        "ecosystem": "Go",
        "name": "goshs.de/goshs/v2"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.1.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-50138"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-284"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-01T21:56:40Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "# WebDAV listener ignores `--read-only`, `--upload-only`, and `--no-delete` mode flags\n\n**Ecosystem:** Go\n**Package:** `goshs.de/goshs/v2` (`github.com/patrickhener/goshs`)\n**Affected:** `\u003c= v2.0.9` (every release that ships the WebDAV handler)\n\n## Summary\n\nWhen `goshs` is launched with WebDAV enabled (`-w`), the mode-restriction flags `--read-only`, `--upload-only`, and `--no-delete` are enforced only on the primary HTTP port. The WebDAV port is wired straight to `golang.org/x/net/webdav.Handler` with no equivalent guard, so an authenticated WebDAV client can `PUT`, `DELETE`, `MKCOL`, `MOVE`, and `COPY` despite the operator\u0027s stated intent.\n\n## Details\n\n[`httpserver/server.go:207-238`](https://github.com/patrickhener/goshs/blob/v2.0.9/httpserver/server.go#L207-L238) \u2014 the WebDAV mux registers only `IPWhitelistMiddleware`, `ServerHeaderMiddleware`, and optionally `BasicAuthMiddleware`. There is no `fs.ReadOnly || fs.UploadOnly || fs.NoDelete` check on the WebDAV path. The HTTP mux in the same file (lines 134-204) does check these flags on every state-changing route.\n\n## Proof of concept\n\n```bash\nmkdir -p /tmp/r \u0026\u0026 echo secret \u003e /tmp/r/x.txt\ngoshs -p 18000 -wp 18001 -w -ro -d /tmp/r -b admin:pw \u0026\n\ncurl -u admin:pw -X PUT    http://localhost:18000/y.txt --data x   # 403  (HTTP enforces -ro)\ncurl -u admin:pw -X PUT    http://localhost:18001/y.txt --data x   # 201  (WebDAV writes anyway)\ncurl -u admin:pw -X DELETE http://localhost:18001/x.txt            # 204  (WebDAV deletes anyway)\ncurl -u admin:pw -X MKCOL  http://localhost:18001/pwned/           # 201  (WebDAV creates dir)\n```\n\n## Impact\n\n- **Integrity** \u2014 `--read-only` and `--no-delete` are silently downgraded to \"no protection\" on the WebDAV port. Any WebDAV client (curl, cadaver, Windows Explorer, Finder) can overwrite/delete files.\n- **Confidentiality** \u2014 `--upload-only` is also bypassed: WebDAV GET/PROPFIND still return file contents.\n- **Trust** \u2014 operators using `goshs -w -ro -d /srv/case-files -b reviewer:pw` to deliver engagement artifacts believe the directory is immutable. It isn\u0027t.\n\n## Suggested fix\n\nAdd a small `http.HandlerFunc` in front of `wdHandler` that maps WebDAV verbs to the existing mode flags:\n\n```go\nwdGuard := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n    switch r.Method {\n    case http.MethodPut, \"MKCOL\", \"MOVE\", \"COPY\":\n        if fs.ReadOnly || fs.UploadOnly { http.Error(w, \"read-only\", 403); return }\n    case http.MethodDelete:\n        if fs.ReadOnly || fs.UploadOnly || fs.NoDelete { http.Error(w, \"delete disabled\", 403); return }\n    case http.MethodGet, \"PROPFIND\", \"HEAD\":\n        if fs.UploadOnly { http.Error(w, \"upload-only\", 403); return }\n    }\n    wdHandler.ServeHTTP(w, r)\n})\n```\n\nAdd regression tests in `integration/functions.go` covering each mode flag \u00d7 each WebDAV verb.\n\nReporter: Nishant Verma. Reproduced live against `goshs v2.0.9` (commit `8fc1e91`) on 2026-05-27.",
  "id": "GHSA-3whc-qvhv-xqjp",
  "modified": "2026-07-01T21:56:40Z",
  "published": "2026-07-01T21:56:40Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/patrickhener/goshs/security/advisories/GHSA-3whc-qvhv-xqjp"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/patrickhener/goshs"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "goshs: WebDAV listener ignores --read-only, --upload-only, and --no-delete mode flags"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

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…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…