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.
The most common type of XSS attack occurs when a web application fails to properly sanitize user input before displaying it to other users. When a site fails to properly address user input, attackers can inject HTML code, which can be particularly dangerous if it is malicious JavaScript code. If an attacker successfully injects JavaScript into a site, they can hijack user sessions, steal cookies, and even send passwords to external servers.
One lesser-known vector for XSS attacks is the SVG image format. SVGs support JavaScript using the <script> tag, which can be exploited by attackers. Here is an example:
<svg>
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">alert("xss");</script>
</svg>
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.
There are three common ways of preventing XSS attacks via SVGs:
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.
Also published here.