GHSA-JP3Q-WWP3-PWV9

Vulnerability from github – Published: 2026-01-22 21:41 – Updated: 2026-01-22 21:42
VLAI?
Summary
Freeform Craft Plugin CP UI (builder/integrations) has Stored Cross-Site Scripting (XSS) issue
Details

Summary An authenticated, low-privilege user (able to create/edit forms) can inject arbitrary HTML/JS into the Craft Control Panel (CP) builder and integrations views. User-controlled form labels and integration metadata are rendered with dangerouslySetInnerHTML without sanitization, leading to stored XSS that executes when any admin views the builder/integration screens.

Affected Product - Ecosystem: Packagist (Craft CMS plugin) - Package: solspace/craft-freeform - Version: <= 5.14.6 (latest observed). Likely all 5.x until patched.

Details - Root cause: Multiple user-controlled strings (field labels, section labels, integration icons, short names, WYSIWYG previews) are injected into React components using dangerouslySetInnerHTML without sanitization. - Evidence: dangerouslySetInnerHTML on user-controlled properties in bundled CP JS at packages/plugin/src/Resources/js/client/client.js.

PoCs - Label-based XSS: 1. In Craft CP, create/edit a Freeform field and set its label to <img src=x onerror="alert('xss-label')">. 2. Open the form builder view containing the field. 3. Alert executes (stored XSS). - Integration icon SVG: 1. Set an integration "icon SVG" to <svg><script>alert('xss-icon')</script></svg>. 2. Open the integrations CP view. 3. Script executes.

Impact Arbitrary JS in admin CP; session/CSRF token theft; potential full admin takeover via DOM-driven actions.

Remediation - Sanitize/HTML-encode all user-controlled strings before passing to dangerouslySetInnerHTML, or avoid it for labels/titles/icons. - Server-side: strip/escape disallowed tags on save for fields, integration metadata, WYSIWYG content. - Add regression tests with <img onerror> payloads to ensure no execution in builder/integration views.

Workarounds - Restrict form-edit permissions to trusted admins only until patched. - Consider CSP that disallows inline scripts (defense-in-depth only).

Credits - Discovered by https://www.linkedin.com/in/praveenkavinda/ | Prav33N-Sec.

Disclosure / CVE Request - Request CVE for this confirmed stored XSS.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 5.14.6"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "solspace/craft-freeform"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "5.14.7"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-79"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-01-22T21:41:14Z",
    "nvd_published_at": null,
    "severity": "LOW"
  },
  "details": "**Summary**\nAn authenticated, low-privilege user (able to create/edit forms) can inject arbitrary HTML/JS into the Craft Control Panel (CP) builder and integrations views. User-controlled form labels and integration metadata are rendered with `dangerouslySetInnerHTML` without sanitization, leading to stored XSS that executes when any admin views the builder/integration screens.\n\n**Affected Product**\n- Ecosystem: Packagist (Craft CMS plugin)\n- Package: solspace/craft-freeform\n- Version: \u003c= 5.14.6 (latest observed). Likely all 5.x until patched.\n\n**Details**\n- Root cause: Multiple user-controlled strings (field labels, section labels, integration icons, short names, WYSIWYG previews) are injected into React components using `dangerouslySetInnerHTML` without sanitization.\n- Evidence: `dangerouslySetInnerHTML` on user-controlled properties in bundled CP JS at [packages/plugin/src/Resources/js/client/client.js](packages/plugin/src/Resources/js/client/client.js#L1).\n\n**PoCs**\n- Label-based XSS:\n  1. In Craft CP, create/edit a Freeform field and set its label to `\u003cimg src=x onerror=\"alert(\u0027xss-label\u0027)\"\u003e`.\n  2. Open the form builder view containing the field.\n  3. Alert executes (stored XSS).\n- Integration icon SVG:\n  1. Set an integration \"icon SVG\" to `\u003csvg\u003e\u003cscript\u003ealert(\u0027xss-icon\u0027)\u003c/script\u003e\u003c/svg\u003e`.\n  2. Open the integrations CP view.\n  3. Script executes.\n\n**Impact**\nArbitrary JS in admin CP; session/CSRF token theft; potential full admin takeover via DOM-driven actions.\n\n**Remediation**\n- Sanitize/HTML-encode all user-controlled strings before passing to `dangerouslySetInnerHTML`, or avoid it for labels/titles/icons.\n- Server-side: strip/escape disallowed tags on save for fields, integration metadata, WYSIWYG content.\n- Add regression tests with `\u003cimg onerror\u003e` payloads to ensure no execution in builder/integration views.\n\n**Workarounds**\n- Restrict form-edit permissions to trusted admins only until patched.\n- Consider CSP that disallows inline scripts (defense-in-depth only).\n\n**Credits**\n- Discovered by https://www.linkedin.com/in/praveenkavinda/ | Prav33N-Sec.\n\n**Disclosure / CVE Request**\n- Request CVE for this confirmed stored XSS.",
  "id": "GHSA-jp3q-wwp3-pwv9",
  "modified": "2026-01-22T21:42:16Z",
  "published": "2026-01-22T21:41:14Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/solspace/craft-freeform/security/advisories/GHSA-jp3q-wwp3-pwv9"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/solspace/craft-freeform"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N/E:P",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Freeform Craft Plugin CP UI (builder/integrations) has Stored Cross-Site Scripting (XSS) issue"
}


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…