# pre-auth Stored XSS in comments via javascript: url when administrator edits user supplied comment

Pre-auth commenter stores a javascript: URL obfuscated with \x3a; when an admin edits/saves the comment, shortcode_parse_atts() decodes it and stored XSS fires.

- Payout: hidden
- Severity: high
- Program: WordPress
- Found by: simonscannell
- Disclosed: 2020-08-18
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/633231
- Library page: https://bugbountylibrary.com/r/h1%3A633231
- Tags: area:web domain:web impact:integrity kind:bounty platform:hackerone sev:high tech:php technique:incomplete-fix technique:source-review vuln:xss

**Target:** WordPress core comment filtering (wp_rel_nofollow_callback / shortcode_parse_atts)
**Root cause:** wp_rel_nofollow_callback() rebuilds <a> tags from shortcode_parse_atts() output when a rel attribute exists; shortcode_parse_atts() applies stripcslashes(), decoding \x3a to ':' and bypassing esc_url() scheme filtering.
**Steps:**
1. As unauthenticated user, submit comment containing `<a href="javascript\x3aalert(1);">Visit my web page</a>`
2. Submit a second comment asking admin to fix a typo in the URL
3. Log in as admin, edit the first comment and click save
4. View the comment on the post and click the link; alert() fires
**How found:** Code review of wp_rel_nofollow_callback() noticed the rel-set branch rebuilds attributes via shortcode_parse_atts(); traced that function to stripcslashes() and realized \x3a decodes to ':' after esc_url() filtering.
**Exploitation:** Attacker plants obfuscated javascript: link in a comment; social-engineers an admin into editing/saving the comment, which triggers the vulnerable rebuild path and stores the decoded javascript: href; victim clicks the link to execute script in site origin.
**Escalation:** XSS could be triggered via clickjacking to reduce interaction; author claims RCE potential from admin-context XSS.
**Insight:** When a sanitizer re-parses and re-serializes HTML attributes, check for escape-decoding functions (stripcslashes, urldecode) applied after URL scheme validation—obfuscated schemes like javascript\x3a survive the first filter and decode on rebuild.

