The vulnerability is a stored Cross-Site Scripting (XSS) issue within the Statamic CMS, specifically related to how custom SVG icons are handled in the control panel navigation. Authenticated users with permissions to manage navigation could upload or specify a malicious SVG icon.
The analysis of the security patch f41c33297fb1b906694e02b4c2a22d3eac823df6 reveals two key areas where the vulnerability existed:
-
Backend (PHP): The Statamic\CP\Navigation\NavItem.svg() method was responsible for retrieving the SVG icon. It would return the raw SVG content without any sanitization. If a user provided a malicious SVG string as an icon (e.g., <svg onload=alert(1)>), this raw string would be saved and later rendered in the control panel for other users, including administrators, to view.
-
Frontend (Vue.js): The SvgIcon.vue component's evaluateIcon method would receive the SVG string (either as a custom icon or as the name prop). It then used this string directly as a Vue template to dynamically render the icon. This is dangerous because Vue will compile and render the template, executing any JavaScript embedded within it.
The patch addresses these issues by introducing sanitization at both levels:
- On the backend, the
rhukster/dom-sanitizer library is used within the newly added sanitizeSvg method to clean the SVG before it's returned by the NavItem::svg() method.
- On the frontend,
DOMPurify is used to sanitize the SVG string within the evaluateIcon method before it's used to create a dynamic Vue component.
Therefore, any runtime profile during the exploitation of this vulnerability would show calls to Statamic\CP\Navigation\NavItem.svg() on the server-side and SvgIcon.evaluateIcon() on the client-side, as these are the functions that directly process the malicious SVG input.