Low severityNVD Advisory· Published Nov 17, 2011· Updated Apr 29, 2026
CVE-2011-4457
CVE-2011-4457
Description
OWASP HTML Sanitizer (aka owasp-java-html-sanitizer) before 88, when JavaScript is disabled, allows user-assisted remote attackers to obtain potentially sensitive information via a crafted FORM element within a NOSCRIPT element.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizerMaven | < 88 | 88 |
Affected products
5cpe:2.3:a:owasp-java-html-sanitizer_project:owasp-java-html-sanitizer:*:*:*:*:*:*:*:*+ 4 more
- cpe:2.3:a:owasp-java-html-sanitizer_project:owasp-java-html-sanitizer:*:*:*:*:*:*:*:*range: <=83
- cpe:2.3:a:owasp-java-html-sanitizer_project:owasp-java-html-sanitizer:42:*:*:*:*:*:*:*
- cpe:2.3:a:owasp-java-html-sanitizer_project:owasp-java-html-sanitizer:48:*:*:*:*:*:*:*
- cpe:2.3:a:owasp-java-html-sanitizer_project:owasp-java-html-sanitizer:50:*:*:*:*:*:*:*
- cpe:2.3:a:owasp-java-html-sanitizer_project:owasp-java-html-sanitizer:74:*:*:*:*:*:*:*
Patches
12027d3df73f6Rework handling of raw-text elements to avoid browser confusion
6 files changed · +104 −16
Makefile+1 −1 modified@@ -1,6 +1,6 @@ CLASSPATH=lib/guava-libraries/guava.jar:lib/jsr305/jsr305.jar TEST_CLASSPATH=$(CLASSPATH):lib/htmlparser-1.3/htmlparser-1.3.jar:lib/junit/junit.jar:lib/commons-codec-1.4/commons-codec-1.4.jar:benchmark-data -JAVAC_FLAGS=-source 1.5 -target 1.5 -Xlint +JAVAC_FLAGS=-source 1.5 -target 1.5 -Xlint -encoding UTF-8 default: javadoc runtests findbugs
src/main/org/owasp/html/HtmlStreamRenderer.java+25 −3 modified@@ -149,7 +149,7 @@ public final void openTag(String elementName, List<String> attrs) { private void writeOpenTag(String elementName, List<? extends String> attrs) throws IOException { if (!open) { throw new IllegalStateException(); } - elementName = HtmlLexer.canonicalName(elementName); + elementName = safeName(elementName); if (!isValidHtmlName(elementName)) { error("Invalid element name", elementName); return; @@ -160,8 +160,8 @@ private void writeOpenTag(String elementName, List<? extends String> attrs) } switch (HtmlTextEscapingMode.getModeForTag(elementName)) { + case CDATA_SOMETIMES: case CDATA: - case CDATA_SOMETIMES: case PLAIN_TEXT: lastTagOpened = elementName; pendingUnescaped = new StringBuilder(); @@ -206,7 +206,7 @@ private void writeOpenTag(String elementName, List<? extends String> attrs) public final void closeTag(String elementName) { try { - writeCloseTag(elementName); + writeCloseTag(safeName(elementName)); } catch (IOException ex) { ioExHandler.handle(ex); } @@ -446,6 +446,28 @@ static void appendNumericEntity(int codepoint, Appendable output) '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', }; + /** + * Canonicalizes the element name and possibly substitutes an alternative + * that has more consistent semantics. + */ + static String safeName(String elementName) { + elementName = HtmlLexer.canonicalName(elementName); + + // Substitute a reliably non-raw-text element for raw-text and + // plain-text elements. + switch (elementName.length()) { + case 3: + if ("xmp".equals(elementName)) { return "pre"; } + break; + case 7: + if ("listing".equals(elementName)) { return "pre"; } + break; + case 9: + if ("plaintext".equals(elementName)) { return "pre"; } + break; + } + return elementName; + } static class CloseableHtmlStreamRenderer extends HtmlStreamRenderer implements Closeable {
src/main/org/owasp/html/HtmlTextEscapingMode.java+10 −9 modified@@ -85,16 +85,19 @@ enum HtmlTextEscapingMode { private static final ImmutableMap<String, HtmlTextEscapingMode> ESCAPING_MODES = ImmutableMap.<String, HtmlTextEscapingMode>builder() .put("iframe", CDATA) - // HTML5 does not treat listing as CDATA, but HTML2 does - // at http://www.w3.org/MarkUp/1995-archive/NonStandard.html + // HTML5 does not treat listing as CDATA and treats XMP as deprecated, + // but HTML2 does at + // http://www.w3.org/MarkUp/1995-archive/NonStandard.html // Listing is not supported by browsers. .put("listing", CDATA_SOMETIMES) + .put("xmp", CDATA) - // Technically, only if embeds, frames, and scripts, respectively, are - // enabled. - .put("noembed", CDATA_SOMETIMES) - .put("noframes", CDATA_SOMETIMES) - .put("noscript", CDATA_SOMETIMES) + // Technically, noembed, noscript and noframes are CDATA_SOMETIMES but + // we can only be hurt by allowing tag content that looks like text so + // we treat them as regular.. + //.put("noembed", CDATA_SOMETIMES) + //.put("noframes", CDATA_SOMETIMES) + //.put("noscript", CDATA_SOMETIMES) .put("comment", CDATA_SOMETIMES) // IE only // Runs till end of file. @@ -107,8 +110,6 @@ enum HtmlTextEscapingMode { .put("textarea", RCDATA) .put("title", RCDATA) - .put("xmp", CDATA) - // Nodes that can't contain content. // http://www.w3.org/TR/html-markup/syntax.html#void-elements .put("area", VOID)
src/tests/org/owasp/html/HtmlPolicyBuilderFuzzerTest.java+2 −2 modified@@ -56,7 +56,7 @@ public class HtmlPolicyBuilderFuzzerTest extends FuzzyTestCase { final Function<HtmlStreamEventReceiver, HtmlSanitizer.Policy> policyFactory = new HtmlPolicyBuilder() - .allowElements("a", "b", "xmp") + .allowElements("a", "b", "xmp", "pre") .allowAttributes("href").onElements("a") .allowAttributes("title").globally() .allowStandardUrlProtocols() @@ -129,7 +129,7 @@ private static void checkSafe(Node node, String html) { switch (node.getNodeType()) { case Node.ELEMENT_NODE: String name = node.getNodeName(); - if (!"a".equals(name) && !"b".equals(name) && !"xmp".equals(name)) { + if (!"a".equals(name) && !"b".equals(name) && !"pre".equals(name)) { fail("Illegal element name " + name + " : " + html); } NamedNodeMap attrs = node.getAttributes();
src/tests/org/owasp/html/HtmlSanitizerTest.java+20 −1 modified@@ -412,6 +412,25 @@ public final void testInnerHTMLIE8() throws Exception { sanitize("<div title=\"``onmouseover=alert(1337)\">")); } + public final void testNabobsOfNegativism() throws Exception { + // Treating <noscript> as raw-text gains us nothing security-wise. + assertEquals("<noscript></noscript>", + sanitize("<noscript><evil></noscript>")); + assertEquals("<noscript>I <b><3</b> Ponies</noscript>", + sanitize("<noscript>I <b><3</b> Ponies</noscript>")); + assertEquals("<noscript>I <b><3</b> Ponies</noscript>", + sanitize("<NOSCRIPT>I <b><3</b> Ponies</noscript><evil>")); + assertEquals("<noframes>I <b><3</b> Ponies</noframes>", + sanitize("<noframes>I <b><3</b> Ponies</noframes><evil>")); + assertEquals("<noembed>I <b><3</b> Ponies</noembed>", + sanitize("<noembed>I <b><3</b> Ponies</noembed><evil>")); + assertEquals("<noxss>I <b><3</b> Ponies</noxss>", + sanitize("<noxss>I <b><3</b> Ponies</noxss><evil>")); + assertEquals( + "<noscript>I <b><3</b> Ponies</noscript>", + sanitize("<xmp><noscript>I <b><3</b> Ponies</noscript></xmp>")); + } + private static String sanitize(@Nullable String html) throws Exception { StringBuilder sb = new StringBuilder(); HtmlStreamRenderer renderer = HtmlStreamRenderer.create( @@ -426,7 +445,7 @@ public void handle(String errorMessage) { // Allow these tags. .allowElements( "a", "b", "br", "div", "i", "img", "input", "li", - "ol", "p", "span", "ul") + "ol", "p", "span", "ul", "noscript", "noframes", "noembed", "noxss") // And these attributes. .allowAttributes( "dir", "checked", "class", "href", "id", "target", "title", "type")
src/tests/org/owasp/html/HtmlStreamRendererTest.java+46 −0 modified@@ -248,6 +248,52 @@ public final void testAppendNumericEntity() throws Exception { sb.toString()); } + // Test that policies that naively allow <xmp>, <listing>, or <plaintext> + // on XHTML don't shoot themselves in the foot. + + public final void testPreSubstitutes1() throws Exception { + renderer.openDocument(); + renderer.openTag("Xmp", ImmutableList.<String>of()); + renderer.text("<form>Hello, World</form>"); + renderer.closeTag("Xmp"); + renderer.closeDocument(); + + assertEquals("<pre><form>Hello, World</form></pre>", + rendered.toString()); + } + + public final void testPreSubstitutes2() throws Exception { + renderer.openDocument(); + renderer.openTag("xmp", ImmutableList.<String>of()); + renderer.text("<form>Hello, World</form>"); + renderer.closeTag("xmp"); + renderer.closeDocument(); + + assertEquals("<pre><form>Hello, World</form></pre>", + rendered.toString()); + } + + public final void testPreSubstitutes3() throws Exception { + renderer.openDocument(); + renderer.openTag("LISTING", ImmutableList.<String>of()); + renderer.text("<form>Hello, World</form>"); + renderer.closeTag("LISTING"); + renderer.closeDocument(); + + assertEquals("<pre><form>Hello, World</form></pre>", + rendered.toString()); + } + + public final void testPreSubstitutes4() throws Exception { + renderer.openDocument(); + renderer.openTag("plaintext", ImmutableList.<String>of()); + renderer.text("<form>Hello, World</form>"); + renderer.closeDocument(); + + assertEquals("<pre><form>Hello, World</form>", + rendered.toString()); + } + private void assertNormalized(String golden, String htmlInput) throws Exception { assertEquals(golden, normalize(htmlInput));
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- code.google.com/p/owasp-java-html-sanitizer/wiki/CVE20114457nvdPatchWEB
- github.com/advisories/GHSA-pcm9-fp55-563vghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2011-4457ghsaADVISORY
- owasp-java-html-sanitizer.googlecode.com/svn/trunk/CHANGE_LOG.htmlnvdWEB
- github.com/OWASP/java-html-sanitizer/blob/35c506cfd452dba634202f13a7cc2e2a63ad7ee0/change_log.mdghsaWEB
- github.com/OWASP/java-html-sanitizer/blob/35c506cfd452dba634202f13a7cc2e2a63ad7ee0/docs/cve20114457.mdghsaWEB
- github.com/OWASP/java-html-sanitizer/commit/2027d3df73f62eb30b7f08269f346989f03144bdghsaWEB
News mentions
0No linked articles in our index yet.