Advisories for Composer/Winter/Wn-Backend-Module package

2026

Winter: Stored XSS through cached Brand Settings and Editor Settings custom styles

Users with the backend.manage_branding ("Customize the back-end") or backend.manage_editor ("Manage global code editor preferences") permission can provide custom CSS through Settings → Customize Backend → Styles or Settings → Editor Settings → Markup Styles that is compiled through the LESS CSS parser and rendered on every backend page. v1.2.13 addressed CVE-2026-32257 and CVE-2026-32258 by applying strip_tags() to the compiled output of BrandSetting::renderCss() and EditorSetting::renderCss(). That fix was incomplete. Both methods …

Winter: Stored XSS through Backend List widget image columns

Backend\Widgets\Lists::evalImageTypeValue() interpolated the resolved image URL into a single-quoted src attribute without escaping it. Where a list column of type image rendered an attacker-influenced value, that value could break out of the attribute and inject arbitrary attributes — including event handlers — into the backend list, executing in the session of whichever backend user viewed it. Winter core ships no image list column, so a default installation is unaffected. Exploitation …

Winter: Reflected XSS through the search query parameter in the backend Table widget

Affected versions of Winter CMS render the search query parameter without HTML encoding inside a <script type="text/template"> block in the backend Table widget partial (modules/backend/widgets/table/partials/_table.php): value="<?= get('search') ?>" <script> is an HTML raw-text context, so the surrounding value="…" attribute quoting is not a parser boundary. A literal </script> in the query string terminates the template element early, and everything after it is parsed as ordinary markup in the backend document. …

Winter: My Account preview exposes another backend user's profile by record ID

Backend\Controllers\MyAccount, introduced in v1.2.13, declares an empty $requiredPermissions array so that any authenticated backend user can manage their own account. It implements the FormController behavior, which exposes three routable actions — create, update and preview — that each take a record id from the URL. index() passes the authenticated user's own id to the behavior, but the inherited actions were left routable and formFindModelObject() was not scoped, so a caller-supplied …

Winter: Local File Inclusion through @import directives in LESS compilation of backend customizable stylesheets and theme assets

Affected versions of Winter CMS allow authenticated backend users with the following permissions to disclose arbitrary files readable by the PHP process by injecting @import (inline) "<path>" directives into LESS source that the backend compiles. Four entry points share the same root cause: Brand Settings BrandSetting.custom_css field (backend.manage_branding) — compiled inline into every backend page's <style> block. Editor Settings EditorSetting.html_custom_styles field (backend.manage_editor) — compiled inline into every backend page's <style> …

Winter: ImportExportController AJAX handlers bypass granular import/export permission gate

Affected versions of Winter CMS did not enforce the ImportExportController behavior's granular access control on the handlers that actually perform the work. The behavior supports per-operation access control through the import[permissions] and export[permissions] configuration keys, enforced by userHasAccess(). That check was applied only to the import() and export() page actions. Backend\Classes\Controller::execAjaxHandlers() dispatches AJAX handlers and returns before execPageAction() runs, and the behavior binds its import and export form widgets in …

Winter: CSRF through AJAX handler names reachable as backend page actions

Affected versions of Winter CMS allow a backend AJAX handler to be invoked by a plain top-level GET navigation with no CSRF token. Backend\Classes\Controller::actionExists() accepted any public method on a controller as a page action, so handler-shaped names were never reserved from URL dispatch: an authenticated and authorized request to /backend/system/eventlogs/index_onEmptyLog reached the handler of the same name and truncated the system event log. Backend paths are routed through Route::any, …

Winter: Authenticated IDOR in backend FileUpload widget allows cross-user access to attachment metadata

The backend FileUpload form widget trusted an attacker-controlled file_id POST parameter when resolving the attachment it operates on. The lookup (FileUpload::getFileRecord()) resolved the posted id against the global system_files table without verifying that the file belonged to the widget's own relation, parent record, or deferred-binding session. Any authenticated backend user who can reach a form containing a fileupload field — including the built-in My Account avatar field, which requires no …

Winter: Stored XSS through Editor Settings custom styles

Authenticated Backend Users with the backend.manage_editor ("Manage editor settings") permission can provide custom styles through Settings → Editor Settings → Markup Styles that are compiled through the LESS CSS parser and rendered on every backend page. Previously, the compiled output was not sanitized, which could have allowed a stored XSS attack. Although this is a valid security issue, it's important to note that its severity is relatively low. To exploit …

Winter: Stored XSS through Brand Settings custom styles

Users with the backend.manage_branding ("Customize the back-end") permission can provide custom CSS through Settings → Customize Backend → Styles that is compiled through the LESS CSS parser and rendered on every backend page. Previously, the compiled output was not sanitized, which could have allowed a stored XSS attack. Although this is a valid security issue, it's important to note that its severity is relatively low. To exploit the vulnerability, an …

Winter: SQL Injection in Backend Filter Widget numberrange Scope via numbersFromAjax

The Backend Filter widget (Backend\Widgets\Filter) is vulnerable to SQL injection through the numberrange scope type when the scope is configured with a conditions key. An authenticated backend user with access to a list view containing a vulnerable filter scope can inject arbitrary SQL via the filter's AJAX handler, potentially gaining read access to the full database contents. To exploit this, an attacker must have a valid backend account with access …

Winter: Authenticated backend users can bypass Users controller permission checks

Affected versions of Winter CMS did not validate the handler name submitted through the form postback mechanism (_handler POST field) in the same way as AJAX requests (X_WINTER_REQUEST_HANDLER header). The AJAX path validates that handler names match the on[A-Z][\w+]* pattern, but the postback path passed the handler name directly to the handler dispatcher with no validation. This allowed an authenticated backend user to call any method on a controller — …

Winter vulnerable to privilege escalation by authenticated backend users

Affected versions of Winter CMS allowed authenticated backend users to escalate their accounts level of access to the system by modifying the roles / permissions assigned to their account through specially crafted requests to the backend while logged in. To actively exploit this security issue, an attacker would need access to the Backend with a user account with any level of access. The Winter CMS maintainers strongly recommend that all …

2024

Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Winter is a free, open-source content management system. Users with access to backend forms that include a ColorPicker FormWidget can provide a value that would then be included without further processing in the compilation of custom stylesheets via LESS. This had the potential to lead to a Local File Inclusion vulnerability. This issue has been patched in v1.2.4.

2023