Feb 19, 2026·6 min read·33 visits
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.
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.
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:
/\evil.com// and the trailing /. It does not strip the \ because it wasn't in the cutset. The string becomes \evil.com./\evil.com.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.
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.
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:
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.https://legit-bank.com/\attacker-site.com/login/legit-bank.com. It looks safe. They click.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./\. 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.
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:
go get -u github.com/go-chi/chi/v5@v5.2.4.go list -m all | grep chi).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.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
github.com/go-chi/chi/v5 go-chi | >= 5.2.2, < 5.2.4 | 5.2.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-601 |
| Attack Vector | Network |
| CVSS Score | 4.7 (Medium) |
| Impact | Open Redirect / Phishing |
| Browser Behavior | Treats '/\' as '//' |
| Patched Version | 5.2.4 |
URL Redirection to Untrusted Site ('Open Redirect')
NocoDB is subject to an insufficient session expiration vulnerability where OAuth access and refresh tokens are not invalidated or revoked during security-sensitive actions such as password changes, forgot-password requests, or password resets. This allows an attacker possessing an active OAuth token to maintain unauthorized persistence.
A vulnerability in the vantage6 federated learning framework allows unauthenticated remote attackers to gain administrative control of the server via hardcoded default credentials (root/root) when deployed under default configurations in versions 4.2.3 and below.
An improper access control vulnerability in the vantage6 node component allows concurrently running algorithm containers to read and modify sensitive input and output files of other tasks. The lack of strict workspace directory isolation exposes a significant attack surface in multi-tenant or federated environments where untrusted algorithms are executed.
TinyMCE versions 6.8.0 through 7.0.1 contain a high-severity Cross-Site Scripting (XSS) vulnerability. The flaw exists in the custom HTML parser and sanitizer module, which incorrectly manages SVG namespace scopes when parsing nested elements. A low-privileged or unauthenticated attacker can submit a crafted HTML payload containing nested SVG structures to bypass sanitization filters, leading to arbitrary JavaScript execution in the context of the victim's browser session.
CVE-2026-47759 is a critical stored Cross-Site Scripting (XSS) vulnerability affecting multiple active branches of the TinyMCE rich text editor. The flaw resides in the editor's handling of user-controlled, prefixed internal attributes, such as data-mce-href, data-mce-src, and data-mce-style. When processing raw HTML inputs, TinyMCE's internal validation schema neglects to inspect these custom prefixed attributes. During HTML serialization, the editor's engine extracts these unsanitized values and copies them back into standard executable attributes, overwriting any previously sanitized standard values and leading to execution of arbitrary code.
A high-severity stored Cross-Site Scripting (XSS) vulnerability was identified in the TinyMCE rich text editor. The flaw exists in the handling of the 'protect' configuration option, where forged placeholder comments containing malicious payloads bypass the editor's sanitization routines and execute arbitrary JavaScript during serialization and content restoration.