Skip to content

Commit 4149cf0

Browse files
committed
1 parent b98cdf1 commit 4149cf0

2 files changed

Lines changed: 41 additions & 12 deletions

File tree

owasp-java-html-sanitizer/src/main/java/org/owasp/html/ElementAndAttributePolicyBasedSanitizerPolicy.java

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -162,26 +162,32 @@ private String stripDisallowedTags(String text) {
162162
// Only process if this looks like a valid HTML element tag
163163
// Valid tags start with a letter or / followed by a letter
164164
// Skip things like <, </>, <3, etc.
165+
// Also handle tags with leading whitespace like < script>
165166
boolean isValidTag = false;
166167
String tagName = null;
167168

168-
if (tagContent.startsWith("/")) {
169+
// Trim leading whitespace for tag name detection
170+
String trimmedTagContent = tagContent.trim();
171+
172+
if (trimmedTagContent.startsWith("/")) {
169173
// Closing tag - must have / followed by a letter
170-
if (tagContent.length() > 1) {
171-
char firstChar = tagContent.charAt(1);
174+
if (trimmedTagContent.length() > 1) {
175+
char firstChar = trimmedTagContent.charAt(1);
172176
if (Character.isLetter(firstChar)) {
173177
isValidTag = true;
174-
tagName = tagContent.substring(1).trim().split("\\s")[0];
178+
tagName = trimmedTagContent.substring(1).trim().split("\\s")[0];
175179
tagName = HtmlLexer.canonicalElementName(tagName);
176180
}
177181
}
178182
} else {
179-
// Opening tag - must start with a letter
180-
char firstChar = tagContent.charAt(0);
181-
if (Character.isLetter(firstChar)) {
182-
isValidTag = true;
183-
tagName = tagContent.trim().split("\\s")[0];
184-
tagName = HtmlLexer.canonicalElementName(tagName);
183+
// Opening tag - must start with a letter (after trimming whitespace)
184+
if (trimmedTagContent.length() > 0) {
185+
char firstChar = trimmedTagContent.charAt(0);
186+
if (Character.isLetter(firstChar)) {
187+
isValidTag = true;
188+
tagName = trimmedTagContent.split("\\s")[0];
189+
tagName = HtmlLexer.canonicalElementName(tagName);
190+
}
185191
}
186192
}
187193

@@ -224,8 +230,9 @@ private String stripDisallowedTags(String text) {
224230
break;
225231
}
226232
String nextTagContent = text.substring(nextTagStart + 1, nextTagEnd);
227-
String nextTagName = nextTagContent.trim().split("\\s")[0];
228-
if (nextTagContent.startsWith("/")) {
233+
String trimmedNextTagContent = nextTagContent.trim();
234+
String nextTagName = trimmedNextTagContent.split("\\s")[0];
235+
if (trimmedNextTagContent.startsWith("/")) {
229236
// Closing tag
230237
nextTagName = nextTagName.substring(1);
231238
nextTagName = HtmlLexer.canonicalElementName(nextTagName);

owasp-java-html-sanitizer/src/test/java/org/owasp/html/HtmlSanitizerTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,28 @@ public static final void testCVE202566021_5() {
584584
assertEquals(expectedPayload, sanitized);
585585
}
586586

587+
/**
588+
* Test that <script> tags with space < script> are sanitized correctly.
589+
*/
590+
@Test
591+
public static final void testCVE202566021_6() {
592+
// Arrange: Attempt to inject a <script> inside <style>. Only 'style' and 'noscript' elements are allowed.
593+
String actualPayload = "<noscript><style>/* user content */.x { font-size: 12px; }< script>alert('XSS Attack!')</script></style></noscript>";
594+
String expectedPayload = "<noscript><style>/* user content */.x { font-size: 12px; }</style></noscript>";
595+
596+
HtmlPolicyBuilder htmlPolicyBuilder = new HtmlPolicyBuilder();
597+
PolicyFactory policy = htmlPolicyBuilder
598+
.allowElements("style", "noscript")
599+
.allowTextIn("style")
600+
.toFactory();
601+
602+
// Act
603+
String sanitized = policy.sanitize(actualPayload);
604+
605+
// Assert
606+
assertEquals(expectedPayload, sanitized);
607+
}
608+
587609
private static String sanitize(@Nullable String html) {
588610
StringBuilder sb = new StringBuilder();
589611
HtmlStreamRenderer renderer = HtmlStreamRenderer.create(

0 commit comments

Comments
 (0)