Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1310 CNY

100%

CVE-2025-46721 PoC — nosurf vulnerable to CSRF due to non-functional same-origin request checks

Source
Associated Vulnerability
Title:nosurf vulnerable to CSRF due to non-functional same-origin request checks (CVE-2025-46721)
Description:nosurf is cross-site request forgery (CSRF) protection middleware for Go. A vulnerability in versions prior to 1.2.0 allows an attacker who controls content on the target site, or on a subdomain of the target site (either via XSS, or otherwise) to bypass CSRF checks and issue requests on user's behalf. Due to misuse of the Go `net/http` library, nosurf categorizes all incoming requests as plain-text HTTP requests, in which case the `Referer` header is not checked to have the same origin as the target webpage. If the attacker has control over HTML contents on either the target website (e.g. `example.com`), or on a website hosted on a subdomain of the target (e.g. `attacker.example.com`), they will also be able to manipulate cookies set for the target website. By acquiring the secret CSRF token from the cookie, or overriding the cookie with a new token known to the attacker, `attacker.example.com` is able to craft cross-site requests to `example.com`. A patch for the issue was released in nosurf 1.2.0. In lieu of upgrading to a patched version of nosurf, users may additionally use another HTTP middleware to ensure that a non-safe HTTP request is coming from the same origin (e.g. by requiring a `Sec-Fetch-Site: same-origin` header in the request).
Readme
# [CVE-2025-46721](https://www.cve.org/CVERecord?id=CVE-2025-46721): CSRF due to non-functional same-origin checks in justinas/nosurf 

<!-- vim-markdown-toc GFM -->

* [What happened?](#what-happened)
* [Am I affected?](#am-i-affected)
* [PoC](#poc)
* [Patching](#patching)
* [Acknowledgements](#acknowledgements)

<!-- vim-markdown-toc -->

## What happened?

All versions of nosurf before 1.2.0 failed to apply same-origin checks for incoming requests.
This happened due to relying on the `.URL.Scheme` field on Go standard library's `net/http.Request` type
to first ensure that the request is served over HTTPS, and only then apply same-origin checks.
The aforementioned `Scheme` field is not filled out by the Go HTTP server on incoming requests:

>     // For server requests, the URL is parsed from the URI
>     // supplied on the Request-Line as stored in RequestURI.  For
>     // most requests, fields other than Path and RawQuery will be
>     // empty.
>
> https://pkg.go.dev/net/http#Request

as in the general case Go can not tell whether the request is happening over TLS
(due to a possible presence of a TLS-terminating reverse proxy, etc.).

This may allow attackers to issue non-[safe](https://developer.mozilla.org/en-US/docs/Glossary/Safe/HTTP) cross-origin requests 
to your website.

## Am I affected?

In addition to implementing same-origin checks, nosurf additionally protects from CSRF using a [double-submit cookie patern](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#naive-double-submit-cookie-pattern-discouraged).
This means that, to successfully make a mutating cross-origin request,
the attacker also needs control over the contents of a page on your website,
or on a subdomain of your website.
This can be achieved via XSS, or if you intentionally give control of the HTML content for users on your website
(e.g. you are a hosting provider `example.com` that allows users to host their websites at `alice.example.com`).

The PoC in this repository demonstrates such attack in the latter case,
where attacker has control of the content on a subdomain of the website's main domain.

## PoC

Requires Go and Caddy. Run the servers manually:

```console
$ go run attacker.go & go run target.go & caddy run
```

or via Process Compose:

```console
$ process-compose
```

Visit `https://attacker.target.localhost`.
Click the button to submit the form to `https://target.localhost` and observe that the request completes successfully.

## Patching

A fix for this issue was released in [nosurf 1.2.0](https://github.com/justinas/nosurf/releases/tag/v1.2.0).

## Acknowledgements

Thanks to Patrick O'Doherty for reporting the issue.
File Snapshot

Log in to view the POC file snapshot cached by Shenlong Bot

Log in to view
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →