Atomic Edge analysis of CVE-2026-2509:
This vulnerability concerns a stored cross-site scripting (XSS) flaw in the Page Builder: Pagelayer plugin for WordPress, up to version 2.0.8. The issue resides in the Button widget’s Custom Attributes field. The plugin attempts to filter XSS via the ‘pagelayer_xss_content’ function, but its blocklist of event handlers is incomplete. An attacker with Contributor-level access or higher can inject arbitrary HTML and JavaScript into pages. When other users, including administrators, view these pages, the injected script executes. The CVSS score is 6.4 (Medium).
Root Cause: The root cause is in the ‘pagelayer/main/functions.php’ file, specifically within the ‘pagelayer_xss_content’ function around line 1290. The function maintains a blocklist ‘$not_allowed’ that lists common event handler attributes (e.g., ‘onclick’, ‘onmouseover’). The diff shows the addition of ‘selectstart’ and ‘selectionchange’ to this list, proving that the original list was incomplete. The ‘pagelayer_sanitize_text_field’ function (called elsewhere) does not sanitize attributes in a way that prevents event handler injection. The Custom Attributes input for the Button widget is not properly sanitized and is only passed through this flawed XSS filter. An attacker can supply an event handler like ‘onselectstart’ (which was not blocked before the patch) to execute JavaScript.
Exploitation: An attacker with at least Contributor-level access edits a page or post using the Pagelayer builder. They add a Button widget and navigate to the widget’s Custom Attributes field. The attacker supplies a malicious attribute, for example: ‘ onselectstart=alert(1) ‘. The quotation marks and attribute name bypass the incomplete blocklist. The plugin saves this payload without proper validation. The stored payload becomes part of the rendered page. When any user views the page (e.g., an admin), the browser triggers the ‘onselectstart’ event (or another unblocked event), executing the attacker’s script.
Patch Analysis: The patch adds ‘selectstart’ and ‘selectionchange’ to the ‘$not_allowed’ array in ‘pagelayer/main/functions.php’. This expands the blocklist to include these two previously missed event handlers. The update increments the version from 2.0.8 to 2.0.9. This fix is a band-aid; it adds specific missing event handlers but does not fundamentally change the sanitization logic to block all event handlers generically. Atomic Edge research notes that this approach is fragile. A future evolution of HTML or a more obscure event handler could bypass the blocklist again. A more robust solution would be to strip ‘on*’ attributes entirely or use a whitelist approach.
Impact: Successful exploitation allows an authenticated attacker with Contributor-level access to inject arbitrary JavaScript into WordPress pages. This script executes in the context of any user viewing the compromised page. An attacker can steal session cookies, perform administrative actions on behalf of an admin, redirect users to malicious sites, or deface the website. The attack can lead to full site compromise if an administrator views the infected page.
