Conversation
…on (XSS Challenge 5) badUrlValidate() spliced its whitelisted 'URL' straight into a double-quoted href="" attribute in XssChallengeFive, but only HTML-encoded the FIRST double quote it found (replaceFirst) while every other dangerous character (#, <, >) was correctly replaceAll'd. A payload with one harmless decoy quote up front left a later, real quote un-encoded, letting an attacker close the href attribute early and splice in a brand new onmouseover/ onerror/onclick attribute - HTML parsers accept a new attribute immediately after a closing quote with no whitespace required. Fix: replaceAll instead of replaceFirst so every quote is neutralised, plus a defence-in-depth check that the parsed URL's protocol is actually http/ https before it is ever returned, in case URL parsing/normalisation could otherwise smuggle another scheme through. Verified locally against the real compiled classes (outside the servlet container): the pre-fix code lets payloads like http:"foo"onmouseover="alert(1) produce <a href="http:"foo"onmouseover="alert(1)">...</a> which FindXSS.search() flags as XSS; the fixed code HTML-encodes every quote so the same payloads are no longer detected as XSS, while legitimate http(s) links are unaffected and still render as a clickable link. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
🏆 Security Shepherd — CTF Patch Score1 / 40 challenges patched
Commit: 🎉 Your result is on the leaderboard — see where you rank! 🏆 |
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…reflow mismatch Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Author
|
Closing as part of a full stand-down of this CTF push. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Challenge
Challenge-39-XSS-5 / Cross Site Scripting 5 (A05)
Vulnerability
XssChallengeFivebuilds<a href="" + XssFilter.badUrlValidate(searchTerm) + "">fromuser input.
badUrlValidate()correctly HTML-encoded#,<, and>withreplaceAll,but only encoded the first double quote with
replaceFirst. A payload containing oneharmless decoy quote up front left a later, real quote un-encoded, letting an attacker close
the
href=""attribute early and splice in a brand new event-handler attribute(
onmouseover/onerror/onclick) — HTML parsers accept a new attribute immediately aftera closing quote even with no whitespace in between.
Example: input
http:"foo"onmouseover="alert(1)survived as<a href="http:"foo"onmouseover="alert(1)">Your HTTP Link!</a>, which the app's ownXSS detector (
FindXSS.search) flags as a successful attribute-injection XSS.Fix
utils/XssFilter.badUrlValidate: encode every double quote (replaceAllinstead ofreplaceFirst), matching the pattern already used for the other special characters.http/httpsbefore returning it, in case URL parsing/normalisation could otherwisesmuggle another scheme through.
anotherBadUrlValidate(used only by the separate XSS Challenge 6) is untouched.Testing
Verified locally by compiling the real
utils.XssFilter/utils.FindXSSclasses directly(outside the servlet container, isolating this specific code path):
onerror/onclickvariants) producedFindXSS.search(...) == true(successful attribute-injection XSS).FindXSS.search(...) == false.http://example.com/page?x=1,https://example.com/) are unchanged andstill render as a normal clickable anchor, and are never flagged as XSS.
Also added
src/test/java/utils/XssChallengeFiveExploitTest.java, a JUnit reproduction of thesame doPost() output-construction chain, covering the three attribute-breakout payloads and two
legitimate-link cases.