Cross-site scripting (XSS) is a type of security vulnerability commonly found in web applications. Attackers exploit XSS vulnerabilities to inject malicious code into a site, which can then be executed on the server or other users' browsers. While modern web frameworks like Ruby on Rails and Phoenix offer built-in protections against basic XSS attacks, XSS is still a prevalent threat that can compromise sensitive user data.
For instance, imagine a user uploads an SVG file with a script embedded in it that steals their session cookie when viewed by other users on the same site. If the web application fails to sanitize the uploaded SVG and renders it as-is, the script will execute and the attacker can access the victim's session.
Similarly, if the application proxies SVGs from an external source, an attacker could inject malicious scripts into the SVG file, and the web application will unwittingly serve the malicious content to its users. This can lead to various types of attacks, such as phishing, data theft, and session hijacking.
Putting shields in place
There are three common ways of preventing XSS attacks via SVGs:
- Adding a stricter Content-Security-Policy header on the route that serves the SVG file.
- Sanitizing SVG files by removing scripts before rendering.
- Or converting SVGs to rasterized formats like PNG and JPG.
I've recently fixed this vulnerability on Plausible, an open-source analytics tool. You can check my commit here. The server acted as a proxy and loaded favicons from external sources to be displayed on Plausible's site. I opted to add the stricter CSP header, meaning that any scripts included in the SVG file will only be executed if they come from the same origin as the webpage that is serving the file. Any attempt to load content from a different origin will be blocked by the browser.
By following best practices for secure coding and staying vigilant for lesser-known attack vectors like SVG, web developers can help protect their users' data from the threat of XSS attacks.