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

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

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

[4.0K] /data/pocs/3747c99a2353ebb4759c4b13b2f086124146f766 ├── [2.3K] attacker.go ├── [ 277] Caddyfile ├── [ 131] go.mod ├── [ 340] go.sum ├── [ 192] process-compose.yaml ├── [2.7K] README.md ├── [ 107] shell.nix └── [1.1K] target.go 0 directories, 8 files
Shenlong Bot has cached this for you
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 →