CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-RHF7-WVW3-VJVM
8.8

GHSA-RHF7-WVW3-VJVM: Cross-Origin Arbitrary File Write via Missing CSRF Protection in goshs

Amit Schendel
Amit Schendel
Senior Security Researcher

Apr 23, 2026·7 min read·6 visits

PoC Available

Executive Summary (TL;DR)

goshs < 2.0.3 allows unauthenticated attackers to write arbitrary files via a victim's browser by combining a missing CSRF token check on PUT requests with a wildcard CORS policy.

The goshs application, a single-binary file server written in Go, suffers from a Cross-Origin Arbitrary File Write vulnerability. The flaw exists due to an incomplete security patch that neglected to enforce Cross-Site Request Forgery (CSRF) protections on the HTTP PUT method. When combined with an overly permissive Cross-Origin Resource Sharing (CORS) configuration that unconditionally reflects Origin headers, an attacker can coerce a victim's browser into writing arbitrary files to the server.

Vulnerability Overview

The goshs utility operates as a lightweight, single-binary file server built in Go. It is frequently deployed on local networks or developer workstations to quickly share files or host static assets. The application exposes an HTTP interface that supports file retrieval, listing, and uploading. The upload functionality is accessible via both POST and PUT HTTP methods, routing through handlers defined in the httpserver/updown.go file.

This vulnerability represents a chained exploit utilizing two distinct security failures: CWE-352 (Cross-Site Request Forgery) and CWE-942 (Permissive Cross-Domain Policy with Untrusted Domains). The core issue resides in an incomplete remediation of a prior security flaw (GHSA-jrq5-hg6x-j6g3). While the developer successfully implemented CSRF token validation for POST requests, the PUT request handler was entirely overlooked.

Compounding the missing CSRF protection is the server's approach to Cross-Origin Resource Sharing (CORS). The goshs server implements a permissive CORS policy by dynamically reflecting any incoming Origin header directly into the Access-Control-Allow-Origin response header. This implementation effectively creates a wildcard CORS configuration, instructing modern web browsers to permit cross-origin requests from any arbitrary domain, including those controlled by an attacker.

The resulting attack surface exposes the local filesystem to external modification. If a developer or user has a goshs instance running locally (e.g., bound to localhost:8080), an attacker can execute state-changing operations against that server simply by convincing the user to visit an external website. The vulnerability requires no direct network access from the attacker to the victim's local network, leveraging the victim's browser as a conduit.

Root Cause Analysis

The root cause of GHSA-RHF7-WVW3-VJVM is fundamentally an incomplete patch application combined with insecure default header management. In the Go ecosystem, securing HTTP endpoints against CSRF typically involves generating a cryptographic token, passing it to the client, and validating it on every state-changing HTTP request (POST, PUT, DELETE, PATCH).

In the goshs codebase, the httpserver/updown.go file manages file upload operations. Following the disclosure of GHSA-jrq5-hg6x-j6g3, the maintainers introduced a checkCSRF() validation function. This function was correctly integrated into the upload() handler, which parses multipart/form-data from HTTP POST requests. However, RESTful design patterns often allow file creation or replacement via the HTTP PUT method. The putHandler() function, responsible for processing these PUT requests, did not receive the checkCSRF() implementation.

Secondary to the CSRF omission is the CORS configuration. The W3C Fetch specification requires web browsers to enforce the Same-Origin Policy (SOP). To relax SOP for APIs, servers must explicitly authorize external origins via the Access-Control-Allow-Origin header. When a browser executes a cross-origin request using methods other than GET, HEAD, or POST (or POST with specific content types), it first dispatches a Preflight request using the HTTP OPTIONS method.

The goshs server intercepts these OPTIONS requests and automatically echoes the value of the request's Origin header back in the response. By satisfying the browser's Preflight checks unconditionally, the server nullifies the protections offered by the Same-Origin Policy. When the browser subsequently issues the PUT request, the server processes it without requiring a CSRF token, finalizing the root cause chain.

Code Analysis

An examination of the httpserver/updown.go file reveals the architectural discrepancy between the POST and PUT handlers. Prior to version 2.0.3, the code paths diverged significantly in their security posture.

The POST handler correctly implemented the validation requirement. As shown in the functional logic of the vulnerable version, the upload() function evaluates the request before reading the request body:

func (s *HTTPServer) upload(w http.ResponseWriter, r *http.Request) {
    // Proper CSRF validation applied to POST requests
    if !s.checkCSRF(w, r) {
        http.Error(w, "CSRF token invalid", http.StatusForbidden)
        return
    }
    // ... processes multipart/form-data ...
}

Conversely, the PUT handler bypassed this validation phase entirely. The server immediately transitioned to creating the file and copying the request body into the file stream:

func (s *HTTPServer) putHandler(w http.ResponseWriter, r *http.Request) {
    // VULNERABILITY: Missing checkCSRF validation
    
    filePath := filepath.Join(s.Webroot, r.URL.Path)
    out, err := os.Create(filePath)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer out.Close()
    
    // Directly copies the payload into the filesystem
    io.Copy(out, r.Body)
}

The remediation in version 2.0.3 introduces the identical checkCSRF() validation routine to the top of the putHandler() function. Furthermore, the patch addresses the permissive CORS policy by implementing strict origin evaluation, ensuring that the Access-Control-Allow-Origin header is only populated when the incoming Origin explicitly matches a pre-approved list or the server's own origin.

Exploitation Methodology

Exploiting this vulnerability relies on a classic Cross-Site Request Forgery attack model, tailored for cross-origin APIs. The attacker must first deploy a malicious HTML page containing specialized JavaScript. The victim must then navigate to this webpage while the goshs server is running on their local machine or within a reachable network segment.

The malicious JavaScript leverages the standard fetch() API to initiate an HTTP PUT request targeting the victim's local goshs instance. The payload explicitly defines the HTTP method and supplies the malicious file content within the request body.

// Proof of Concept Payload hosted on attacker.com
fetch('http://localhost:8080/pwned.txt', {
    method: 'PUT',
    headers: {
        'Content-Type': 'text/plain'
    },
    body: 'Arbitrary file write successful via Cross-Origin PUT.'
}).then(response => {
    console.log('Exploit delivered:', response.status);
});

> [!NOTE] > The attack sequence depends heavily on the browser's Preflight mechanics.

When the victim loads the attacker's page, the browser identifies the cross-origin PUT request. It pauses the execution and sends an HTTP OPTIONS request to http://localhost:8080/pwned.txt. The vulnerable goshs server responds with Access-Control-Allow-Origin: http://attacker.com. The browser interprets this as explicit authorization and proceeds to dispatch the actual PUT request. The goshs server, lacking CSRF checks on PUT operations, receives the request, writes the payload to the disk, and returns an HTTP 200 OK.

Impact Assessment

The successful exploitation of GHSA-RHF7-WVW3-VJVM results in arbitrary file write capabilities within the directory served by the goshs instance. The severity of this impact is highly dependent on the operational context in which the server is deployed, but it fundamentally compromises the integrity of the filesystem.

If the goshs server is serving a directory containing source code, configuration files, or script interpreters, the attacker can overwrite critical assets. For example, overwriting an existing script file that the victim later executes directly translates the file write into local code execution. If goshs is serving an active web root (e.g., HTML/JS files), the attacker can drop a persistent Cross-Site Scripting (XSS) payload or a web shell.

The vulnerability does not inherently provide read access or immediate remote code execution, which slightly limits the base CVSS score. Furthermore, the attack requires user interaction; the victim must actively browse to an attacker-controlled site. However, because goshs is designed as a developer tool, instances are frequently executed from high-privilege directories (such as a user's home directory or project root), elevating the practical risk of arbitrary file modification.

Remediation and Mitigation

The primary remediation for this vulnerability is upgrading the goshs binary to version 2.0.3 or later. The patch introduces robust CSRF validation across all state-changing HTTP methods and implements secure CORS handling to reject untrusted cross-origin requests.

Security teams managing automated deployments or developer environments should audit systems for running instances of goshs. If immediate patching is not feasible, administrators must enforce network-level mitigations. This includes binding the goshs server exclusively to the loopback interface (127.0.0.1) rather than all interfaces (0.0.0.0), preventing exposure to local area networks.

Developers utilizing localized file servers should operate them with the least privilege necessary. Servers should only be started within isolated, non-critical directories. Avoid running temporary HTTP servers from the system root, user home directories, or environments containing sensitive credential files (e.g., ~/.aws/ or ~/.ssh/).

Official Patches

GitHub AdvisoryPrimary Security Advisory
patrickhenerUpstream Repository

Technical Appendix

CVSS Score
8.8/ 10

Affected Systems

patrickhener/goshs versions prior to 2.0.3

Affected Versions Detail

Product
Affected Versions
Fixed Version
goshs
patrickhener
< 2.0.32.0.3
AttributeDetail
CWE IDCWE-352 / CWE-942
Attack VectorNetwork (Requires Victim Interaction)
ImpactArbitrary File Write
Exploit StatusPoC Available
AuthenticationNone Required
Componenthttpserver/updown.go (putHandler)

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1189Drive-by Compromise
Initial Access
CWE-352
Cross-Site Request Forgery (CSRF)

The application does not adequately verify that a request was intentionally provided by the user who submitted the request, combined with an overly permissive CORS configuration.

Vulnerability Timeline

Vulnerability Disclosed and Advisory Published
2026-04-20
Version 2.0.3 Released with Patch
2026-04-20

References & Sources

  • [1]GHSA-RHF7-WVW3-VJVM Security Advisory
  • [2]goshs GitHub Repository
  • [3]Related Advisory (Incomplete Fix for POST uploads)
Related Vulnerabilities
GHSA-jrq5-hg6x-j6g3

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.