Skip to content

Fix reflected XSS in Cross Site Scripting Challenge 6 (attribute breakout via 2nd quote/angle-bracket) - #341

Closed
beanbeah wants to merge 1 commit into
OWASP-CTF:dc34-ctffrom
beanbeah:ctf/r2-challenge-challenge-40-xss-6
Closed

beanbeah wants to merge 1 commit into
OWASP-CTF:dc34-ctffrom
beanbeah:ctf/r2-challenge-challenge-40-xss-6

Conversation

@beanbeah

@beanbeah beanbeah commented Aug 9, 2026

Copy link
Copy Markdown

Challenge-40-XSS-6

XssChallengeSix.doPost reflects the user's searchTerm into <a href="...">Your HTTP Link!</a> after running it through XssFilter.anotherBadUrlValidate.

That sanitizer only escaped the first occurrence of <, >, and " (via replaceFirst). A payload containing a second occurrence of any of those characters (e.g. http://a/x"onmouseover="alert(1) or http://a/x<i>text</i><img src=x onerror=alert(1)>) sailed through with that later character completely unescaped, closing the href="" attribute early and letting an attacker inject a brand-new live attribute/tag on the anchor element — a reflected XSS bypass of the filter.

Fix

Switch all of <, >, " to replaceAll (every occurrence, not just the first) and also encode ' for defense in depth. Legitimate http(s) links, which don't contain these characters, are unaffected.

Local verification (WSL)

Full mvn compile/full container stack was heavily contended by many concurrent sibling builds in the shared sandbox (timed out at 400s), so I compiled just utils/XssFilter.java + utils/FindXSS.java directly with javac against the project's cached Maven dependencies, and drove them with a standalone harness that reproduces XssChallengeSix.doPost's exact reflection logic (sanitize -> wrap in <a href> -> FindXSS.search):

  • Pre-fix: both exploit payloads reflect with the raw "/</> intact in the rendered <a> tag (confirmed exploitable attribute/tag breakout).
  • Post-fix: both payloads are fully HTML-entity encoded, no breakout possible.
  • Legitimate link (http://www.example.com/path?x=1) renders identically before and after the fix.

Only src/main/java/utils/XssFilter.java was changed.

…Validate

XssChallengeSix reflects a user-supplied searchTerm into <a href="...">
after passing it through XssFilter.anotherBadUrlValidate(). That method
only escaped the FIRST occurrence of '<', '>', and '"' (replaceFirst),
so a second, later occurrence of any of those characters survived
untouched and let an attacker close the href attribute early and inject
a brand new HTML attribute (e.g. onmouseover=alert(1)) or a whole new
tag, achieving reflected XSS despite the filter.

Switch all four breakout characters (plus single quote, for defense in
depth) to replaceAll so every occurrence is neutralised, not just the
first. Legitimate http(s) links are unaffected since they don't contain
these characters.

Challenge-40-XSS-6
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

🏆 Security Shepherd — CTF Patch Score

█░░░░░░░░░░░░░░░░░░░  3 / 79 pts  (4%)

1 / 40 challenges patched

Per-challenge detail is withheld — it would reveal the rubric.

Commit: e8e06c0 · scoring run

🎉 Your result is on the leaderboard — see where you rank! 🏆

@beanbeah

beanbeah commented Aug 9, 2026

Copy link
Copy Markdown
Author

Closing as part of a full stand-down of this CTF push.

@beanbeah beanbeah closed this Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant