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-MQQF-5WVP-8FH8
4.70.10%

The Slash That Wasn't: Exploiting go-chi's Clean Paths

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 19, 2026·6 min read·9 visits

PoC Available

Executive Summary (TL;DR)

The 'RedirectSlashes' middleware in go-chi/chi versions 5.2.2 through 5.2.3 fails to sanitize backslashes. An attacker can use a payload like '/\evil.com/' which the server normalizes to '/\evil.com'. Browsers interpret this as a protocol-relative URL (effectively '//evil.com'), redirecting the victim to an external malicious site.

A logic flaw in the popular Go router 'chi' allows attackers to bypass URL sanitization and trigger open redirects. By exploiting browser normalization quirks and a weak string trimming implementation, an attacker can craft a payload that looks like a relative path to the server but acts as an absolute URL in the browser.

The Hook: Clean URLs, Dirty Tricks

In the world of web development, we are obsessed with hygiene. We want our URLs clean, our slashes normalized, and our SEO scores optimized. The go-chi/chi router, a lightweight and idiomatic router for Go, offers a handy piece of middleware called RedirectSlashes. Its job is simple: take a messy URL like /api/users/// and politely guide the user to /api/users. It's the digital equivalent of a frantic host tidying up the living room before guests arrive.

But here is the thing about tidying up: if you sweep the dust under the rug, you haven't actually cleaned anything; you've just hidden the mess until someone trips over the lump. In this specific case, the RedirectSlashes middleware was so focused on managing forward slashes (/) that it completely forgot about the existence of the backslash (\).

This oversight turns a feature designed to improve user experience into a classic Open Redirect vulnerability. It is not the kind of bug that will dump your database or grant you a root shell (sorry, RCE hunters), but it is exactly the kind of bug that turns your trusted domain into a launchpad for phishing campaigns. It is a subtle disagreement between how a Go server sees a string and how a Chrome browser sees a URL.

The Flaw: A Tale of Two Slashes

To understand this vulnerability, you have to understand the mechanism of failure. The middleware intends to strip trailing slashes and ensure the path starts with a root slash. It does this to prevent duplicate content issues (SEO) and to keep routing logic strict. The flaw lies in the assumption that the only character used to delimit paths is the forward slash.

The vulnerability exists because RedirectSlashes uses Go's strings.Trim(path, "/"). This function creates a 'cutset' containing only the forward slash. It aggressively eats any forward slashes at the beginning or end of the string. However, it leaves backslashes completely untouched. If an attacker sends a request to https://target.com/\evil.com/, the server sees a path that needs cleaning.

Here is the logic flow that leads to disaster:

  1. Input: /\evil.com/
  2. Trim: The code strips the leading / and the trailing /. It does not strip the \ because it wasn't in the cutset. The string becomes \evil.com.
  3. Prepend: The code dutifully adds a slash to the front to make it absolute. The result is /\evil.com.
  4. Response: The server sends a 301 Moved Permanently to Location: /\evil.com.

Now, if you or I look at /\evil.com, we might see a relative path on the file system. But web browsers are built on decades of legacy compatibility code. When Chrome, Firefox, or Edge see a URL starting with /\, they treat it as a Protocol-Relative URL, identical to starting with //. The browser implicitly uses the current protocol (http or https) and treats the next token as the domain. So, /\evil.com effectively becomes https://evil.com.

The Code: The Smoking Gun

Let's look at the code. This is a classic example of "naive sanitization"—fixing the input you expect rather than sanitizing the input you actually get. Below is the vulnerable logic compared to the patch.

The Vulnerable Code: It blindly trims forward slashes and prepends one. It assumes the resulting string is safe to serve as a redirect location.

// The middleware receives the request path
path := r.URL.Path
 
// ... logic to detect if we need to redirect ...
 
// The Fatal Mistake:
// This removes forward slashes but ignores backslashes
path = "/" + strings.Trim(path, "/")
 
// The server redirects the user to this "cleaned" path
http.Redirect(w, r, path, 301)

The Fix (Commit 6eb3588): The fix is straightforward but vital. Before we start trimming things, we must normalize the input. By converting all backslashes to forward slashes first, the Trim function works as intended.

// The Fix:
// 1. Normalize all backslashes to forward slashes first
path = strings.ReplaceAll(path, `\`, `/`)
 
// 2. NOW we can trim. Since backslashes are gone, 
//    strings.Trim will correctly remove all leading/trailing separators.
path = "/" + strings.Trim(path, "/")
 
http.Redirect(w, r, path, 301)

This simple addition of strings.ReplaceAll kills the exploit dead. Now, path becomes //evil.com/ (normalized), then evil.com (trimmed), then /evil.com (prepended). The browser sees /evil.com, which is a safe, relative path on the origin server. Crisis averted.

The Exploit: Phishing with Style

So, how do we weaponize this? We aren't dropping shellcode here; we are manipulating trust. The goal is to create a link that looks like it belongs to a legitimate domain but sends the user somewhere else. This is a "Trust-Based" attack.

Imagine a scenario where legit-bank.com uses go-chi for its API routing. An attacker wants to steal credentials. They can't hack the bank, but they can trick the bank into redirecting users to a fake login page.

The Attack Chain:

  1. Reconnaissance: The attacker identifies that legit-bank.com strips trailing slashes on its API endpoints. They test https://legit-bank.com/api// and get redirected to /api. This confirms a normalization middleware is likely in play.
  2. Payload Construction: The attacker crafts a phishing email: "URGENT: Your account has been flagged. Click here to verify." The link points to: https://legit-bank.com/\attacker-site.com/login/
  3. Delivery: The user hovers over the link. They see legit-bank.com. It looks safe. They click.
  4. Execution: The legit-bank.com server receives the request. The RedirectSlashes middleware sees the trailing slash and decides to helpfully "clean" the URL. It transforms /\attacker-site.com/login/ into /\attacker-site.com/login and issues a 301 Redirect.
  5. The Pivot: The user's browser receives the 301. It sees the Location header starts with /\. It treats this as a network-path reference (protocol relative). It seamlessly navigates the user to https://attacker-site.com/login.

Because the initial request was to the real bank, and the redirect happens instantly, many users (and even some security tools) won't notice the switch until they've already typed their password into the fake site.

The Mitigation: Stop the Bleeding

If you are running go-chi/chi in production, check your go.mod file immediately. The vulnerable versions are typically in the v5.2.x range (specifically 5.2.2 and 5.2.3, though versioning can be tricky with Go modules). The fix landed in version 5.2.4.

Remediation Steps:

  1. Update: Run go get -u github.com/go-chi/chi/v5@v5.2.4.
  2. Verify: Ensure your build pipeline is actually using the new version (go list -m all | grep chi).
  3. Audit: If you cannot update immediately, you must disable the RedirectSlashes middleware. It is a convenience feature, not a security feature. Removing it will stop the redirects (and the exploit), though your users might see 404s if they type trailing slashes.

For Developers Writing Custom Middleware: This is a lesson in "Input Normalization before Validation." Never assume a URL path contains only standard characters. Browsers are incredibly forgiving of malformed URLs, and that forgiveness is exactly what attackers exploit. If you are trimming paths, you must account for \, %5c, and other weird representations of separators.

Official Patches

GitHubCommit fixing the redirect logic

Fix Analysis (1)

Technical Appendix

CVSS Score
4.7/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:L/A:N
EPSS Probability
0.10%
Top 100% most exploited

Affected Systems

Go applications using chi routerWeb services using RedirectSlashes middleware

Affected Versions Detail

Product
Affected Versions
Fixed Version
github.com/go-chi/chi/v5
go-chi
>= 5.2.2, < 5.2.45.2.4
AttributeDetail
CWE IDCWE-601
Attack VectorNetwork
CVSS Score4.7 (Medium)
ImpactOpen Redirect / Phishing
Browser BehaviorTreats '/\' as '//'
Patched Version5.2.4

MITRE ATT&CK Mapping

T1566Phishing
Initial Access
T1608Stage Capabilities
Resource Development
CWE-601
Open Redirect

URL Redirection to Untrusted Site ('Open Redirect')

Known Exploits & Detection

ManualManual reconstruction of the open redirect using curl and browser behavior analysis.
NucleiDetection Template Available

Vulnerability Timeline

Vulnerability Published
2026-01-14
Patch Released in v5.2.4
2026-01-14

References & Sources

  • [1]GHSA Advisory
  • [2]Go Vulnerability Database

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.