Introduction
Relative Path Overwrite (RPO) is an older, lesser-known vulnerability that still impacts a significant number of applications. This flaw typically allows an attacker to manipulate the browser’s interpretation of a relative path, forcing it to load a malicious file instead of the intended resource (like a stylesheet).
While RPO can sometimes be used for Cross-Site Scripting (XSS) or extracting sensitive data, the vast majority of cases can only be exploited for web defacement by injecting custom CSS. This vulnerability is often classified as a low-severity finding, but it is still interesting because it is frequently missed in security audits due to a lack of understanding regarding the exploit chain.
RPO Prerequisites and Mechanism
Before an RPO attack can be exploited, several specific application conditions must be met:
- Reflected Input: A page must reflect the current URL, path, or
Refererheader in the HTML source of the response. - Quirks Mode Enabled: The HTML page must be missing the
tagto enable the browser’s Quirks Mode. - Wildcard Path: The endpoint must have a wildcard path or “catch-all” routing, meaning a URL like
example.com/vuln.phpresolves to the same page asexample.com/vuln.php/something/. - Relative Path Imports: The page must import resources (like stylesheets) using a relative path (e.g.,
).
If all these requirements are met, an RPO exploit is highly likely.
Understanding Path Relative Links
To understand RPO, you must first know how browsers use path relative links to load content:
- Absolute Link (Full Path):
(Uses the full URL.) - Root-Relative Link:
(Starts at the root of the web directory/.) - Relative Link (Current Directory):
(Looks in the current directory for the file. If the URL isexample.com/test/, it will look for the CSS file at/test/style.css.)
The RPO attack targets the relative link and manipulates the browser’s interpretation of the current directory.
Quirks Mode Explained
Quirks Mode was designed to gracefully handle poorly coded websites, which were common years ago. When Quirks Mode is enabled (by omitting the tag), the browser often ignores the Content-Type header of a file when processing it.
This is critical for RPO: if we pass an HTML file (with a Content-Type: text/html) to a link tag that expects a stylesheet, the browser in Quirks Mode will still try to parse the HTML file as if it is a CSS file. If Quirks Mode is disabled, the browser would block this action and throw an error.
The RPO Exploit Chain
The exploit requires confirming the conditions and then constructing a malicious URL.
Step 1: Confirming Reflection, Quirks Mode, and Wildcard Routing
First, examine the vulnerable code or manually inspect the page source.
The initial step is to determine if the application reflects the URL path in the HTML source. You can manually verify this by checking the source code after visiting a path like /home/okay/.
The reflection of the okay/ path is visible. We can also see that the tag is missing, confirming that the page is running in Quirks Mode. Next, we must confirm that /home/okay/ resolves to the same page as /home, which confirms the wildcard path routing.
Step 2: Manipulating the Relative Path
Because the tag is using a relative path (style.css), when we change the URL to /home/okay/, the browser attempts to import the stylesheet from /home/okay/style.css.
However, due to the wildcard path routing, the URL /home/okay/style.css actually resolves and returns the content of the original HTML page (/home)!
[Image showing the URL structure where /home/okay/ resolves to the same page as /home, but the relative path changes to /home/okay/style.css]
As shown, the Link tag attempts to import its stylesheet from /home/okay/style.css. Because of the wildcard path after /home, this URL resolves to the same HTML source as /home. Since the response does not contain a tag, the browser has Quirks Mode enabled.
If Quirks Mode were disabled, the browser would receive the HTML content with a Content-Type: text/html and would throw an error when attempting to parse it as a stylesheet.
Step 3: Launching the CSS Injection
Since the Link tag is forced to accept the HTML output as CSS (due to Quirks Mode), and user-controlled input is reflected in that output (the path), an attacker can inject CSS commands that the browser will execute.
The malicious URL is crafted by appending the CSS payload to the path:
- Payload:
%0A{}*{color:red;}///(The%0Ais a newline character, used to ensure the injection starts on a new line.)
This CSS payload forces all elements on the page (*) to have a red color.
[Image showing the result of the RPO attack where the font color is red due to CSS injection]
The injection of the CSS code successfully turns the page font red, confirming the target is vulnerable to RPO.
Summary and Conclusion
Relative Path Overwrite is an older, lesser-known vulnerability that still poses a threat. It is a complex attack chain requiring specific application conditions: path reflection, a relative resource link, wildcard routing, and the omission of the tag (enabling Quirks Mode).
While often classified as a low-severity finding, RPO can still be used to perform web defacements and, in rare cases, higher-impact attacks. It is a bug that many security professionals overlook.
You now have a few more sophisticated tricks up your sleeve! There are plenty of other techniques out there, and I recommend learning additional vulnerabilities. The more vulnerabilities you know how to exploit, the better your chances are of securing an application.
