From e8e06c07e47bad2d37fd74442680e686e2050fff Mon Sep 17 00:00:00 2001 From: beanbeah <24713371+beanbeah@users.noreply.github.com> Date: Sun, 9 Aug 2026 11:37:51 -0700 Subject: [PATCH] fix: fully encode attribute-breakout chars in XssFilter.anotherBadUrlValidate XssChallengeSix reflects a user-supplied searchTerm into 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 --- src/main/java/utils/XssFilter.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/utils/XssFilter.java b/src/main/java/utils/XssFilter.java index ad1c27d58..980b40dc5 100644 --- a/src/main/java/utils/XssFilter.java +++ b/src/main/java/utils/XssFilter.java @@ -40,13 +40,18 @@ public static String anotherBadUrlValidate(String input) { input = input.toLowerCase(); if (input.startsWith("http")) { try { + // Every occurrence of an attribute-breakout character must be neutralised, not just the + // first one - a second, un-escaped '<' / '>' / '"' / '\'' later in the string still lets + // an attacker close the surrounding href="" attribute and inject a fresh HTML attribute + // (e.g. onmouseover=alert(1)) or a whole new tag. URL theUrl = new URL( input .replaceAll("#", "#") - .replaceFirst("<", "<") - .replaceFirst(">", ">") - .replaceFirst("\"", """)); + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll("\"", """) + .replaceAll("'", "'")); input = theUrl.toString(); } catch (MalformedURLException e) { log.debug("Could not Cast URL from input: " + e.toString());