Share
## https://sploitus.com/exploit?id=5ECB3DD8-CEE2-5630-A8B2-FC26F3C34072
# [CVE-2025-46721](https://vulners.com/cve/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.