SanitizersTest.java revision be666032a113a8af92bc557add8e83579cf0ef5c
1// Copyright (c) 2011, Mike Samuel 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions 6// are met: 7// 8// Redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer. 10// Redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution. 13// Neither the name of the OWASP nor the names of its contributors may 14// be used to endorse or promote products derived from this software 15// without specific prior written permission. 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 26// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27// POSSIBILITY OF SUCH DAMAGE. 28 29package org.owasp.html; 30 31import org.junit.Test; 32 33import junit.framework.TestCase; 34 35public class SanitizersTest extends TestCase { 36 37 @Test 38 public static final void testFormatting() { 39 assertEquals("", Sanitizers.FORMATTING.sanitize(null)); 40 assertEquals("", Sanitizers.FORMATTING.sanitize("")); 41 assertEquals( 42 "Hello, World!", 43 Sanitizers.FORMATTING.sanitize("Hello, World!")); 44 assertEquals( 45 "Hello, <b>World</b>!", 46 Sanitizers.FORMATTING.sanitize("Hello, <b>World</b>!")); 47 assertEquals( 48 "Hello, <b>World</b>!", 49 Sanitizers.FORMATTING.sanitize( 50 "<p>Hello, <b onclick=alert(1337)>World</b>!</p>")); 51 } 52 53 @Test 54 public static final void testBlockElements() { 55 assertEquals("", Sanitizers.BLOCKS.sanitize(null)); 56 assertEquals( 57 "Hello, World!", 58 Sanitizers.BLOCKS.sanitize("Hello, World!")); 59 assertEquals( 60 "Hello, World!", 61 Sanitizers.BLOCKS.sanitize("Hello, <b>World</b>!")); 62 assertEquals( 63 "<p>Hello, World!</p>", 64 Sanitizers.BLOCKS.sanitize( 65 "<p onclick=alert(1337)>Hello, <b>World</b>!</p>")); 66 } 67 68 @Test 69 public static final void testBlockAndFormattingElements() { 70 PolicyFactory s = Sanitizers.BLOCKS.and(Sanitizers.FORMATTING); 71 PolicyFactory r1 = Sanitizers.BLOCKS.and(Sanitizers.FORMATTING) 72 .and(Sanitizers.BLOCKS); 73 PolicyFactory r2 = Sanitizers.BLOCKS.and(Sanitizers.FORMATTING) 74 .and(Sanitizers.FORMATTING); 75 for (PolicyFactory f : new PolicyFactory[] { s, r1, r2 }) { 76 assertEquals("", f.sanitize(null)); 77 assertEquals("Hello, World!", f.sanitize("Hello, World!")); 78 assertEquals("Hello, <b>World</b>!", f.sanitize("Hello, <b>World</b>!")); 79 assertEquals( 80 "<p>Hello, <b>World</b>!</p>", 81 f.sanitize("<p onclick=alert(1337)>Hello, <b>World</b>!</p>")); 82 } 83 } 84 85 @Test 86 public static final void testAndIntersects() { 87 PolicyFactory restrictedLink = new HtmlPolicyBuilder() 88 .allowElements("a") 89 .allowUrlProtocols("https") 90 .allowAttributes("href", "title").onElements("a") 91 .toFactory(); 92 PolicyFactory inline = Sanitizers.FORMATTING.and(Sanitizers.LINKS); 93 String inputHtml = 94 "<a href='http://foo.com/'>Hello, <b>World</b></a>" 95 + "<a title='!' href='https://foo.com/#!'>!</a>"; 96 PolicyFactory and1 = restrictedLink.and(inline); 97 PolicyFactory and2 = inline.and(restrictedLink); 98 assertEquals( 99 "https-only links", 100 "Hello, World<a title=\"!\" href=\"https://foo.com/#!\">!</a>", 101 restrictedLink.sanitize(inputHtml)); 102 assertEquals( 103 "inline els", 104 "<a href=\"http://foo.com/\" rel=\"nofollow\">Hello, <b>World</b></a>" 105 + "<a href=\"https://foo.com/#!\" rel=\"nofollow\">!</a>", 106 inline.sanitize(inputHtml)); 107 assertEquals( 108 "https-only links and inline els", 109 "Hello, <b>World</b>" 110 + "<a title=\"!\" href=\"https://foo.com/#!\" rel=\"nofollow\">!</a>", 111 and1.sanitize(inputHtml)); 112 assertEquals( 113 "inline els and https-only links", 114 "Hello, <b>World</b>" 115 + "<a title=\"!\" href=\"https://foo.com/#!\" rel=\"nofollow\">!</a>", 116 and2.sanitize(inputHtml)); 117 } 118 119 @Test 120 public static final void testImages() { 121 PolicyFactory s = Sanitizers.IMAGES; 122 assertEquals( 123 "foo", s.sanitize("<a href=\"javascript:alert(1337)\">foo</a>")); 124 assertEquals( 125 "<img src=\"foo.gif\" />", s.sanitize("<img src=\"foo.gif\">")); 126 assertEquals( 127 "", s.sanitize("<img src=\"javascript://alert(1337)\">")); 128 assertEquals( 129 "<img src=\"x.gif\" alt=\"y\"" 130 + " width=\"96\" height=\"64\" border=\"0\" />", 131 s.sanitize( 132 "<img src=\"x.gif\" alt=\"y\" width=96 height=64 border=0>")); 133 assertEquals( 134 "<img src=\"x.png\" alt=\"y\" height=\"64\" border=\"0\" />", 135 s.sanitize( 136 "<img src=\"x.png\" alt=\"y\" width=\"widgy\" height=64 border=0>") 137 ); 138 } 139 140 @Test 141 public static final void testLinks() { 142 PolicyFactory s = Sanitizers.LINKS; 143 assertEquals( 144 "<a href=\"foo.html\" rel=\"nofollow\">Link text</a>", 145 s.sanitize("<a href=\"foo.html\">Link text</a>")); 146 assertEquals( 147 "<a href=\"foo.html\" rel=\"nofollow\">Link text</a>", 148 s.sanitize( 149 "<a href=\"foo.html\" onclick=\"alert(1337)\">Link text</a>")); 150 assertEquals( 151 "<a href=\"http://example.com/x.html\" rel=\"nofollow\">Link text</a>", 152 s.sanitize( 153 "<a href=\"http://example.com/x.html\"" 154 + " onclick=\"alert(1337)\">Link text</a>")); 155 assertEquals( 156 "<a href=\"https://example.com/x.html\" rel=\"nofollow\">Link text</a>", 157 s.sanitize( 158 "<a href=\"https://example.com/x.html\"" 159 + " onclick=\"alert(1337)\">Link text</a>")); 160 assertEquals( 161 "<a href=\"//example.com/x.html\" rel=\"nofollow\">Link text</a>", 162 s.sanitize( 163 "<a href=\"//example.com/x.html\"" 164 + " onclick=\"alert(1337)\">Link text</a>")); 165 assertEquals( 166 "Link text", 167 s.sanitize( 168 "<a href=\"javascript:alert(1337).html\"" 169 + " onclick=\"alert(1337)\">Link text</a>")); 170 // Not a link. Instead, an attempt to intercept URL references that has 171 // not been explicitly allowed. 172 assertEquals( 173 "Header text", 174 s.sanitize("<a name=\"header\" id=\"header\">Header text</a>")); 175 } 176 177 @Test 178 public static final void testIssue9StylesInTables() { 179 String input = "" 180 + "<table style=\"color: rgb(0, 0, 0);" 181 + " font-family: Arial, Geneva, sans-serif;\">" 182 + "<tbody>" 183 + "<tr>" 184 + "<th>Column One</th><th>Column Two</th>" 185 + "</tr>" 186 + "<tr>" 187 + "<td align=\"center\"" 188 + " style=\"background-color: rgb(255, 255, 254);\">" 189 + "<font size=\"2\">Size 2</font></td>" 190 + "<td align=\"center\"" 191 + " style=\"background-color: rgb(255, 255, 254);\">" 192 + "<font size=\"7\">Size 7</font></td>" 193 + "</tr>" 194 + "</tbody>" 195 + "</table>"; 196 PolicyFactory s = new HtmlPolicyBuilder() 197 .allowElements("table", "tbody", "thead", "tr", "td", "th") 198 .allowCommonBlockElements() 199 .allowCommonInlineFormattingElements() 200 .allowStyling() 201 .allowAttributes("align").matching(true, "left", "center", "right") 202 .onElements("table", "tr", "td", "th") 203 .allowAttributes("size").onElements("font", "img") 204 .toFactory(); 205 String sanitized = "" 206 + "<table style=\"font-family:"Arial","Geneva"," 207 + "sans-serif;color:#000\">" 208 + "<tbody>" 209 + "<tr>" 210 + "<th>Column One</th><th>Column Two</th>" 211 + "</tr>" 212 + "<tr>" 213 + "<td align=\"center\" style=\"background-color:#fffffe\">" 214 + "<font size=\"2\">Size 2</font></td>" 215 + "<td align=\"center\" style=\"background-color:#fffffe\">" 216 + "<font size=\"7\">Size 7</font></td>" 217 + "</tr>" 218 + "</tbody>" 219 + "</table>"; 220 assertEquals(sanitized, s.sanitize(input)); 221 } 222} 223