github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/bluemonday/sanitize_test.go (about) 1 // Copyright (c) 2014, David Kitchen <david@buro9.com> 2 // 3 // All rights reserved. 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are met: 7 // 8 // * Redistributions of source code must retain the above copyright notice, this 9 // list of conditions and the following disclaimer. 10 // 11 // * Redistributions in binary form must reproduce the above copyright notice, 12 // this list of conditions and the following disclaimer in the documentation 13 // and/or other materials provided with the distribution. 14 // 15 // * Neither the name of the organisation (Microcosm) nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 package bluemonday 31 32 import ( 33 "encoding/base64" 34 "net/url" 35 "regexp" 36 "strings" 37 "sync" 38 "testing" 39 ) 40 41 // test is a simple input vs output struct used to construct a slice of many 42 // tests to run within a single test method. 43 type test struct { 44 in string 45 expected string 46 } 47 48 func TestEmpty(t *testing.T) { 49 p := StrictPolicy() 50 51 if "" != p.Sanitize(``) { 52 t.Error("Empty string is not empty") 53 } 54 } 55 56 func TestSignatureBehaviour(t *testing.T) { 57 // https://yougam/libraries/microcosm-cc/bluemonday/issues/8 58 p := UGCPolicy() 59 60 input := "Hi.\n" 61 62 if output := p.Sanitize(input); output != input { 63 t.Errorf(`Sanitize() input = %s, output = %s`, input, output) 64 } 65 66 if output := string(p.SanitizeBytes([]byte(input))); output != input { 67 t.Errorf(`SanitizeBytes() input = %s, output = %s`, input, output) 68 } 69 70 if output := p.SanitizeReader( 71 strings.NewReader(input), 72 ).String(); output != input { 73 74 t.Errorf(`SanitizeReader() input = %s, output = %s`, input, output) 75 } 76 77 input = "\t\n \n\t" 78 79 if output := p.Sanitize(input); output != input { 80 t.Errorf(`Sanitize() input = %s, output = %s`, input, output) 81 } 82 83 if output := string(p.SanitizeBytes([]byte(input))); output != input { 84 t.Errorf(`SanitizeBytes() input = %s, output = %s`, input, output) 85 } 86 87 if output := p.SanitizeReader( 88 strings.NewReader(input), 89 ).String(); output != input { 90 91 t.Errorf(`SanitizeReader() input = %s, output = %s`, input, output) 92 } 93 } 94 95 func TestAllowDocType(t *testing.T) { 96 p := NewPolicy() 97 p.AllowElements("b") 98 99 in := "<!DOCTYPE html>Hello, <b>World</b>!" 100 expected := "Hello, <b>World</b>!" 101 102 out := p.Sanitize(in) 103 if out != expected { 104 t.Errorf( 105 "test 1 failed;\ninput : %s\noutput : %s\nexpected: %s", 106 in, 107 out, 108 expected, 109 ) 110 } 111 112 // Allow the doctype and run the test again 113 p.AllowDocType(true) 114 115 expected = "<!DOCTYPE html>Hello, <b>World</b>!" 116 117 out = p.Sanitize(in) 118 if out != expected { 119 t.Errorf( 120 "test 1 failed;\ninput : %s\noutput : %s\nexpected: %s", 121 in, 122 out, 123 expected, 124 ) 125 } 126 } 127 128 func TestLinks(t *testing.T) { 129 130 tests := []test{ 131 test{ 132 in: `<a href="http://www.google.com">`, 133 expected: `<a href="http://www.google.com" rel="nofollow">`, 134 }, 135 test{ 136 in: `<a href="//www.google.com">`, 137 expected: `<a href="//www.google.com" rel="nofollow">`, 138 }, 139 test{ 140 in: `<a href="/www.google.com">`, 141 expected: `<a href="/www.google.com" rel="nofollow">`, 142 }, 143 test{ 144 in: `<a href="www.google.com">`, 145 expected: `<a href="www.google.com" rel="nofollow">`, 146 }, 147 test{ 148 in: `<a href="javascript:alert(1)">`, 149 expected: ``, 150 }, 151 test{ 152 in: `<a href="#">`, 153 expected: ``, 154 }, 155 test{ 156 in: `<a href="#top">`, 157 expected: `<a href="#top" rel="nofollow">`, 158 }, 159 test{ 160 in: `<a href="?">`, 161 expected: ``, 162 }, 163 test{ 164 in: `<a href="?q=1">`, 165 expected: `<a href="?q=1" rel="nofollow">`, 166 }, 167 test{ 168 in: `<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />`, 169 expected: `<img alt="Red dot"/>`, 170 }, 171 test{ 172 in: `<img src="giraffe.gif" />`, 173 expected: `<img src="giraffe.gif"/>`, 174 }, 175 } 176 177 p := UGCPolicy() 178 p.RequireParseableURLs(true) 179 180 // These tests are run concurrently to enable the race detector to pick up 181 // potential issues 182 wg := sync.WaitGroup{} 183 wg.Add(len(tests)) 184 for ii, tt := range tests { 185 go func(ii int, tt test) { 186 out := p.Sanitize(tt.in) 187 if out != tt.expected { 188 t.Errorf( 189 "test %d failed;\ninput : %s\noutput : %s\nexpected: %s", 190 ii, 191 tt.in, 192 out, 193 tt.expected, 194 ) 195 } 196 wg.Done() 197 }(ii, tt) 198 } 199 wg.Wait() 200 } 201 202 func TestLinkTargets(t *testing.T) { 203 204 tests := []test{ 205 test{ 206 in: `<a href="http://www.google.com">`, 207 expected: `<a href="http://www.google.com" rel="nofollow" target="_blank">`, 208 }, 209 test{ 210 in: `<a href="//www.google.com">`, 211 expected: `<a href="//www.google.com" rel="nofollow" target="_blank">`, 212 }, 213 test{ 214 in: `<a href="/www.google.com">`, 215 expected: `<a href="/www.google.com">`, 216 }, 217 test{ 218 in: `<a href="www.google.com">`, 219 expected: `<a href="www.google.com">`, 220 }, 221 test{ 222 in: `<a href="javascript:alert(1)">`, 223 expected: ``, 224 }, 225 test{ 226 in: `<a href="#">`, 227 expected: ``, 228 }, 229 test{ 230 in: `<a href="#top">`, 231 expected: `<a href="#top">`, 232 }, 233 test{ 234 in: `<a href="?">`, 235 expected: ``, 236 }, 237 test{ 238 in: `<a href="?q=1">`, 239 expected: `<a href="?q=1">`, 240 }, 241 test{ 242 in: `<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />`, 243 expected: `<img alt="Red dot"/>`, 244 }, 245 test{ 246 in: `<img src="giraffe.gif" />`, 247 expected: `<img src="giraffe.gif"/>`, 248 }, 249 } 250 251 p := UGCPolicy() 252 p.RequireParseableURLs(true) 253 p.RequireNoFollowOnLinks(false) 254 p.RequireNoFollowOnFullyQualifiedLinks(true) 255 p.AddTargetBlankToFullyQualifiedLinks(true) 256 257 // These tests are run concurrently to enable the race detector to pick up 258 // potential issues 259 wg := sync.WaitGroup{} 260 wg.Add(len(tests)) 261 for ii, tt := range tests { 262 go func(ii int, tt test) { 263 out := p.Sanitize(tt.in) 264 if out != tt.expected { 265 t.Errorf( 266 "test %d failed;\ninput : %s\noutput : %s\nexpected: %s", 267 ii, 268 tt.in, 269 out, 270 tt.expected, 271 ) 272 } 273 wg.Done() 274 }(ii, tt) 275 } 276 wg.Wait() 277 } 278 279 func TestStyling(t *testing.T) { 280 281 tests := []test{ 282 test{ 283 in: `<span class="foo">Hello World</span>`, 284 expected: `<span class="foo">Hello World</span>`, 285 }, 286 test{ 287 in: `<span class="foo bar654">Hello World</span>`, 288 expected: `<span class="foo bar654">Hello World</span>`, 289 }, 290 } 291 292 p := UGCPolicy() 293 p.AllowStyling() 294 295 // These tests are run concurrently to enable the race detector to pick up 296 // potential issues 297 wg := sync.WaitGroup{} 298 wg.Add(len(tests)) 299 for ii, tt := range tests { 300 go func(ii int, tt test) { 301 out := p.Sanitize(tt.in) 302 if out != tt.expected { 303 t.Errorf( 304 "test %d failed;\ninput : %s\noutput : %s\nexpected: %s", 305 ii, 306 tt.in, 307 out, 308 tt.expected, 309 ) 310 } 311 wg.Done() 312 }(ii, tt) 313 } 314 wg.Wait() 315 } 316 317 func TestEmptyAttributes(t *testing.T) { 318 319 p := UGCPolicy() 320 // Do not do this, especially without a Matching() clause, this is a test 321 p.AllowAttrs("disabled").OnElements("textarea") 322 323 tests := []test{ 324 // Empty elements 325 test{ 326 in: `<textarea>text</textarea><textarea disabled></textarea>` + 327 `<div onclick='redirect()'><span>Styled by span</span></div>`, 328 expected: `<textarea>text</textarea><textarea disabled=""></textarea>` + 329 `<div><span>Styled by span</span></div>`, 330 }, 331 test{ 332 in: `foo<br />bar`, 333 expected: `foo<br/>bar`, 334 }, 335 test{ 336 in: `foo<br/>bar`, 337 expected: `foo<br/>bar`, 338 }, 339 test{ 340 in: `foo<br>bar`, 341 expected: `foo<br>bar`, 342 }, 343 test{ 344 in: `foo<hr noshade>bar`, 345 expected: `foo<hr>bar`, 346 }, 347 } 348 349 for ii, test := range tests { 350 out := p.Sanitize(test.in) 351 if out != test.expected { 352 t.Errorf( 353 "test %d failed;\ninput : %s\noutput : %s\nexpected: %s", 354 ii, 355 test.in, 356 out, 357 test.expected, 358 ) 359 } 360 } 361 } 362 363 func TestDataUri(t *testing.T) { 364 365 p := UGCPolicy() 366 p.AllowURLSchemeWithCustomPolicy( 367 "data", 368 func(url *url.URL) (allowUrl bool) { 369 // Allows PNG images only 370 const prefix = "image/png;base64," 371 if !strings.HasPrefix(url.Opaque, prefix) { 372 return false 373 } 374 if _, err := base64.StdEncoding.DecodeString(url.Opaque[len(prefix):]); err != nil { 375 return false 376 } 377 if url.RawQuery != "" || url.Fragment != "" { 378 return false 379 } 380 return true 381 }, 382 ) 383 384 tests := []test{ 385 test{ 386 in: `<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">`, 387 expected: `<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">`, 388 }, 389 test{ 390 in: `<img src="data:text/javascript;charset=utf-8,alert('hi');">`, 391 expected: ``, 392 }, 393 test{ 394 in: `<img src="data:image/png;base64,charset=utf-8,alert('hi');">`, 395 expected: ``, 396 }, 397 test{ 398 in: `<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4-_8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">`, 399 expected: ``, 400 }, 401 } 402 403 for ii, test := range tests { 404 out := p.Sanitize(test.in) 405 if out != test.expected { 406 t.Errorf( 407 "test %d failed;\ninput : %s\noutput : %s\nexpected: %s", 408 ii, 409 test.in, 410 out, 411 test.expected, 412 ) 413 } 414 } 415 } 416 417 func TestAntiSamy(t *testing.T) { 418 419 standardUrls := regexp.MustCompile(`(?i)^https?|mailto`) 420 421 p := NewPolicy() 422 423 p.AllowElements( 424 "a", "b", "br", "div", "font", "i", "img", "input", "li", "ol", "p", 425 "span", "td", "ul", 426 ) 427 p.AllowAttrs("checked", "type").OnElements("input") 428 p.AllowAttrs("color").OnElements("font") 429 p.AllowAttrs("href").Matching(standardUrls).OnElements("a") 430 p.AllowAttrs("src").Matching(standardUrls).OnElements("img") 431 p.AllowAttrs("class", "id", "title").Globally() 432 p.AllowAttrs("char").Matching( 433 regexp.MustCompile(`p{L}`), // Single character or HTML entity only 434 ).OnElements("td") 435 436 tests := []test{ 437 // Base64 strings 438 // 439 // first string is 440 // <a - href="http://www.owasp.org">click here</a> 441 test{ 442 in: `PGEgLSBocmVmPSJodHRwOi8vd3d3Lm93YXNwLm9yZyI+Y2xpY2sgaGVyZTwvYT4=`, 443 expected: `PGEgLSBocmVmPSJodHRwOi8vd3d3Lm93YXNwLm9yZyI+Y2xpY2sgaGVyZTwvYT4=`, 444 }, 445 // the rest are randomly generated 300 byte sequences which generate 446 // parser errors, turned into Strings 447 test{ 448 in: `uz0sEy5aDiok6oufQRaYPyYOxbtlACRnfrOnUVIbOstiaoB95iw+dJYuO5sI9nudhRtSYLANlcdgO0pRb+65qKDwZ5o6GJRMWv4YajZk+7Q3W/GN295XmyWUpxuyPGVi7d5fhmtYaYNW6vxyKK1Wjn9IEhIrfvNNjtEF90vlERnz3wde4WMaKMeciqgDXuZHEApYmUcu6Wbx4Q6WcNDqohAN/qCli74tvC+Umy0ZsQGU7E+BvJJ1tLfMcSzYiz7Q15ByZOYrA2aa0wDu0no3gSatjGt6aB4h30D9xUP31LuPGZ2GdWwMfZbFcfRgDSh42JPwa1bODmt5cw0Y8ACeyrIbfk9IkX1bPpYfIgtO7TwuXjBbhh2EEixOZ2YkcsvmcOSVTvraChbxv6kP`, 449 expected: `uz0sEy5aDiok6oufQRaYPyYOxbtlACRnfrOnUVIbOstiaoB95iw+dJYuO5sI9nudhRtSYLANlcdgO0pRb+65qKDwZ5o6GJRMWv4YajZk+7Q3W/GN295XmyWUpxuyPGVi7d5fhmtYaYNW6vxyKK1Wjn9IEhIrfvNNjtEF90vlERnz3wde4WMaKMeciqgDXuZHEApYmUcu6Wbx4Q6WcNDqohAN/qCli74tvC+Umy0ZsQGU7E+BvJJ1tLfMcSzYiz7Q15ByZOYrA2aa0wDu0no3gSatjGt6aB4h30D9xUP31LuPGZ2GdWwMfZbFcfRgDSh42JPwa1bODmt5cw0Y8ACeyrIbfk9IkX1bPpYfIgtO7TwuXjBbhh2EEixOZ2YkcsvmcOSVTvraChbxv6kP`, 450 }, 451 test{ 452 in: `PIWjMV4y+MpuNLtcY3vBRG4ZcNaCkB9wXJr3pghmFA6rVXAik+d5lei48TtnHvfvb5rQZVceWKv9cR/9IIsLokMyN0omkd8j3TV0DOh3JyBjPHFCu1Gp4Weo96h5C6RBoB0xsE4QdS2Y1sq/yiha9IebyHThAfnGU8AMC4AvZ7DDBccD2leZy2Q617ekz5grvxEG6tEcZ3fCbJn4leQVVo9MNoerim8KFHGloT+LxdgQR6YN5y1ii3bVGreM51S4TeANujdqJXp8B7B1Gk3PKCRS2T1SNFZedut45y+/w7wp5AUQCBUpIPUj6RLp+y3byWhcbZbJ70KOzTSZuYYIKLLo8047Fej43bIaghJm0F9yIKk3C5gtBcw8T5pciJoVXrTdBAK/8fMVo29P`, 453 expected: `PIWjMV4y+MpuNLtcY3vBRG4ZcNaCkB9wXJr3pghmFA6rVXAik+d5lei48TtnHvfvb5rQZVceWKv9cR/9IIsLokMyN0omkd8j3TV0DOh3JyBjPHFCu1Gp4Weo96h5C6RBoB0xsE4QdS2Y1sq/yiha9IebyHThAfnGU8AMC4AvZ7DDBccD2leZy2Q617ekz5grvxEG6tEcZ3fCbJn4leQVVo9MNoerim8KFHGloT+LxdgQR6YN5y1ii3bVGreM51S4TeANujdqJXp8B7B1Gk3PKCRS2T1SNFZedut45y+/w7wp5AUQCBUpIPUj6RLp+y3byWhcbZbJ70KOzTSZuYYIKLLo8047Fej43bIaghJm0F9yIKk3C5gtBcw8T5pciJoVXrTdBAK/8fMVo29P`, 454 }, 455 test{ 456 in: `uCk7HocubT6KzJw2eXpSUItZFGkr7U+D89mJw70rxdqXP2JaG04SNjx3dd84G4bz+UVPPhPO2gBAx2vHI0xhgJG9T4vffAYh2D1kenmr+8gIHt6WDNeD+HwJeAbJYhfVFMJsTuIGlYIw8+I+TARK0vqjACyRwMDAndhXnDrk4E5U3hyjqS14XX0kIDZYM6FGFPXe/s+ba2886Q8o1a7WosgqqAmt4u6R3IHOvVf5/PIeZrBJKrVptxjdjelP8Xwjq2ujWNtR3/HM1kjRlJi4xedvMRe4Rlxek0NDLC9hNd18RYi0EjzQ0bGSDDl0813yv6s6tcT6xHMzKvDcUcFRkX6BbxmoIcMsVeHM/ur6yRv834o/TT5IdiM9/wpkuICFOWIfM+Y8OWhiU6BK`, 457 expected: `uCk7HocubT6KzJw2eXpSUItZFGkr7U+D89mJw70rxdqXP2JaG04SNjx3dd84G4bz+UVPPhPO2gBAx2vHI0xhgJG9T4vffAYh2D1kenmr+8gIHt6WDNeD+HwJeAbJYhfVFMJsTuIGlYIw8+I+TARK0vqjACyRwMDAndhXnDrk4E5U3hyjqS14XX0kIDZYM6FGFPXe/s+ba2886Q8o1a7WosgqqAmt4u6R3IHOvVf5/PIeZrBJKrVptxjdjelP8Xwjq2ujWNtR3/HM1kjRlJi4xedvMRe4Rlxek0NDLC9hNd18RYi0EjzQ0bGSDDl0813yv6s6tcT6xHMzKvDcUcFRkX6BbxmoIcMsVeHM/ur6yRv834o/TT5IdiM9/wpkuICFOWIfM+Y8OWhiU6BK`, 458 }, 459 test{ 460 in: `Bb6Cqy6stJ0YhtPirRAQ8OXrPFKAeYHeuZXuC1qdHJRlweEzl4F2z/ZFG7hzr5NLZtzrRG3wm5TXl6Aua5G6v0WKcjJiS2V43WB8uY1BFK1d2y68c1gTRSF0u+VTThGjz+q/R6zE8HG8uchO+KPw64RehXDbPQ4uadiL+UwfZ4BzY1OHhvM5+2lVlibG+awtH6qzzx6zOWemTih932Lt9mMnm3FzEw7uGzPEYZ3aBV5xnbQ2a2N4UXIdm7RtIUiYFzHcLe5PZM/utJF8NdHKy0SPaKYkdXHli7g3tarzAabLZqLT4k7oemKYCn/eKRreZjqTB2E8Kc9Swf3jHDkmSvzOYE8wi1vQ3X7JtPcQ2O4muvpSa70NIE+XK1CgnnsL79Qzci1/1xgkBlNq`, 461 expected: `Bb6Cqy6stJ0YhtPirRAQ8OXrPFKAeYHeuZXuC1qdHJRlweEzl4F2z/ZFG7hzr5NLZtzrRG3wm5TXl6Aua5G6v0WKcjJiS2V43WB8uY1BFK1d2y68c1gTRSF0u+VTThGjz+q/R6zE8HG8uchO+KPw64RehXDbPQ4uadiL+UwfZ4BzY1OHhvM5+2lVlibG+awtH6qzzx6zOWemTih932Lt9mMnm3FzEw7uGzPEYZ3aBV5xnbQ2a2N4UXIdm7RtIUiYFzHcLe5PZM/utJF8NdHKy0SPaKYkdXHli7g3tarzAabLZqLT4k7oemKYCn/eKRreZjqTB2E8Kc9Swf3jHDkmSvzOYE8wi1vQ3X7JtPcQ2O4muvpSa70NIE+XK1CgnnsL79Qzci1/1xgkBlNq`, 462 }, 463 test{ 464 in: `FZNVr4nOICD1cNfAvQwZvZWi+P4I2Gubzrt+wK+7gLEY144BosgKeK7snwlA/vJjPAnkFW72APTBjY6kk4EOyoUef0MxRnZEU11vby5Ru19eixZBFB/SVXDJleLK0z3zXXE8U5Zl5RzLActHakG8Psvdt8TDscQc4MPZ1K7mXDhi7FQdpjRTwVxFyCFoybQ9WNJNGPsAkkm84NtFb4KjGpwVC70oq87tM2gYCrNgMhBfdBl0bnQHoNBCp76RKdpq1UAY01t1ipfgt7BoaAr0eTw1S32DezjfkAz04WyPTzkdBKd3b44rX9dXEbm6szAz0SjgztRPDJKSMELjq16W2Ua8d1AHq2Dz8JlsvGzi2jICUjpFsIfRmQ/STSvOT8VsaCFhwL1zDLbn5jCr`, 465 expected: `FZNVr4nOICD1cNfAvQwZvZWi+P4I2Gubzrt+wK+7gLEY144BosgKeK7snwlA/vJjPAnkFW72APTBjY6kk4EOyoUef0MxRnZEU11vby5Ru19eixZBFB/SVXDJleLK0z3zXXE8U5Zl5RzLActHakG8Psvdt8TDscQc4MPZ1K7mXDhi7FQdpjRTwVxFyCFoybQ9WNJNGPsAkkm84NtFb4KjGpwVC70oq87tM2gYCrNgMhBfdBl0bnQHoNBCp76RKdpq1UAY01t1ipfgt7BoaAr0eTw1S32DezjfkAz04WyPTzkdBKd3b44rX9dXEbm6szAz0SjgztRPDJKSMELjq16W2Ua8d1AHq2Dz8JlsvGzi2jICUjpFsIfRmQ/STSvOT8VsaCFhwL1zDLbn5jCr`, 466 }, 467 test{ 468 in: `RuiRkvYjH2FcCjNzFPT2PJWh7Q6vUbfMadMIEnw49GvzTmhk4OUFyjY13GL52JVyqdyFrnpgEOtXiTu88Cm+TiBI7JRh0jRs3VJRP3N+5GpyjKX7cJA46w8PrH3ovJo3PES7o8CSYKRa3eUs7BnFt7kUCvMqBBqIhTIKlnQd2JkMNnhhCcYdPygLx7E1Vg+H3KybcETsYWBeUVrhRl/RAyYJkn6LddjPuWkDdgIcnKhNvpQu4MMqF3YbzHgyTh7bdWjy1liZle7xR/uRbOrRIRKTxkUinQGEWyW3bbXOvPO71E7xyKywBanwg2FtvzOoRFRVF7V9mLzPSqdvbM7VMQoLFob2UgeNLbVHkWeQtEqQWIV5RMu3+knhoqGYxP/3Srszp0ELRQy/xyyD`, 469 expected: `RuiRkvYjH2FcCjNzFPT2PJWh7Q6vUbfMadMIEnw49GvzTmhk4OUFyjY13GL52JVyqdyFrnpgEOtXiTu88Cm+TiBI7JRh0jRs3VJRP3N+5GpyjKX7cJA46w8PrH3ovJo3PES7o8CSYKRa3eUs7BnFt7kUCvMqBBqIhTIKlnQd2JkMNnhhCcYdPygLx7E1Vg+H3KybcETsYWBeUVrhRl/RAyYJkn6LddjPuWkDdgIcnKhNvpQu4MMqF3YbzHgyTh7bdWjy1liZle7xR/uRbOrRIRKTxkUinQGEWyW3bbXOvPO71E7xyKywBanwg2FtvzOoRFRVF7V9mLzPSqdvbM7VMQoLFob2UgeNLbVHkWeQtEqQWIV5RMu3+knhoqGYxP/3Srszp0ELRQy/xyyD`, 470 }, 471 test{ 472 in: `mqBEVbNnL929CUA3sjkOmPB5dL0/a0spq8LgbIsJa22SfP580XduzUIKnCtdeC9TjPB/GEPp/LvEUFaLTUgPDQQGu3H5UCZyjVTAMHl45me/0qISEf903zFFqW5Lk3TS6iPrithqMMvhdK29Eg5OhhcoHS+ALpn0EjzUe86NywuFNb6ID4o8aF/ztZlKJegnpDAm3JuhCBauJ+0gcOB8GNdWd5a06qkokmwk1tgwWat7cQGFIH1NOvBwRMKhD51MJ7V28806a3zkOVwwhOiyyTXR+EcDA/aq5acX0yailLWB82g/2GR/DiaqNtusV+gpcMTNYemEv3c/xLkClJc29DSfTsJGKsmIDMqeBMM7RRBNinNAriY9iNX1UuHZLr/tUrRNrfuNT5CvvK1K`, 473 expected: `mqBEVbNnL929CUA3sjkOmPB5dL0/a0spq8LgbIsJa22SfP580XduzUIKnCtdeC9TjPB/GEPp/LvEUFaLTUgPDQQGu3H5UCZyjVTAMHl45me/0qISEf903zFFqW5Lk3TS6iPrithqMMvhdK29Eg5OhhcoHS+ALpn0EjzUe86NywuFNb6ID4o8aF/ztZlKJegnpDAm3JuhCBauJ+0gcOB8GNdWd5a06qkokmwk1tgwWat7cQGFIH1NOvBwRMKhD51MJ7V28806a3zkOVwwhOiyyTXR+EcDA/aq5acX0yailLWB82g/2GR/DiaqNtusV+gpcMTNYemEv3c/xLkClJc29DSfTsJGKsmIDMqeBMM7RRBNinNAriY9iNX1UuHZLr/tUrRNrfuNT5CvvK1K`, 474 }, 475 test{ 476 in: `IMcfbWZ/iCa/LDcvMlk6LEJ0gDe4ohy2Vi0pVBd9aqR5PnRj8zGit8G2rLuNUkDmQ95bMURasmaPw2Xjf6SQjRk8coIHDLtbg/YNQVMabE8pKd6EaFdsGWJkcFoonxhPR29aH0xvjC4Mp3cJX3mjqyVsOp9xdk6d0Y2hzV3W/oPCq0DV03pm7P3+jH2OzoVVIDYgG1FD12S03otJrCXuzDmE2LOQ0xwgBQ9sREBLXwQzUKfXH8ogZzjdR19pX9qe0rRKMNz8k5lqcF9R2z+XIS1QAfeV9xopXA0CeyrhtoOkXV2i8kBxyodDp7tIeOvbEfvaqZGJgaJyV8UMTDi7zjwNeVdyKa8USH7zrXSoCl+Ud5eflI9vxKS+u9Bt1ufBHJtULOCHGA2vimkU`, 477 expected: `IMcfbWZ/iCa/LDcvMlk6LEJ0gDe4ohy2Vi0pVBd9aqR5PnRj8zGit8G2rLuNUkDmQ95bMURasmaPw2Xjf6SQjRk8coIHDLtbg/YNQVMabE8pKd6EaFdsGWJkcFoonxhPR29aH0xvjC4Mp3cJX3mjqyVsOp9xdk6d0Y2hzV3W/oPCq0DV03pm7P3+jH2OzoVVIDYgG1FD12S03otJrCXuzDmE2LOQ0xwgBQ9sREBLXwQzUKfXH8ogZzjdR19pX9qe0rRKMNz8k5lqcF9R2z+XIS1QAfeV9xopXA0CeyrhtoOkXV2i8kBxyodDp7tIeOvbEfvaqZGJgaJyV8UMTDi7zjwNeVdyKa8USH7zrXSoCl+Ud5eflI9vxKS+u9Bt1ufBHJtULOCHGA2vimkU`, 478 }, 479 test{ 480 in: `AqC2sr44HVueGzgW13zHvJkqOEBWA8XA66ZEb3EoL1ehypSnJ07cFoWZlO8kf3k57L1fuHFWJ6quEdLXQaT9SJKHlUaYQvanvjbBlqWwaH3hODNsBGoK0DatpoQ+FxcSkdVE/ki3rbEUuJiZzU0BnDxH+Q6FiNsBaJuwau29w24MlD28ELJsjCcUVwtTQkaNtUxIlFKHLj0++T+IVrQH8KZlmVLvDefJ6llWbrFNVuh674HfKr/GEUatG6KI4gWNtGKKRYh76mMl5xH5qDfBZqxyRaKylJaDIYbx5xP5I4DDm4gOnxH+h/Pu6dq6FJ/U3eDio/KQ9xwFqTuyjH0BIRBsvWWgbTNURVBheq+am92YBhkj1QmdKTxQ9fQM55O8DpyWzRhky0NevM9j`, 481 expected: `AqC2sr44HVueGzgW13zHvJkqOEBWA8XA66ZEb3EoL1ehypSnJ07cFoWZlO8kf3k57L1fuHFWJ6quEdLXQaT9SJKHlUaYQvanvjbBlqWwaH3hODNsBGoK0DatpoQ+FxcSkdVE/ki3rbEUuJiZzU0BnDxH+Q6FiNsBaJuwau29w24MlD28ELJsjCcUVwtTQkaNtUxIlFKHLj0++T+IVrQH8KZlmVLvDefJ6llWbrFNVuh674HfKr/GEUatG6KI4gWNtGKKRYh76mMl5xH5qDfBZqxyRaKylJaDIYbx5xP5I4DDm4gOnxH+h/Pu6dq6FJ/U3eDio/KQ9xwFqTuyjH0BIRBsvWWgbTNURVBheq+am92YBhkj1QmdKTxQ9fQM55O8DpyWzRhky0NevM9j`, 482 }, 483 test{ 484 in: `qkFfS3WfLyj3QTQT9i/s57uOPQCTN1jrab8bwxaxyeYUlz2tEtYyKGGUufua8WzdBT2VvWTvH0JkK0LfUJ+vChvcnMFna+tEaCKCFMIOWMLYVZSJDcYMIqaIr8d0Bi2bpbVf5z4WNma0pbCKaXpkYgeg1Sb8HpKG0p0fAez7Q/QRASlvyM5vuIOH8/CM4fF5Ga6aWkTRG0lfxiyeZ2vi3q7uNmsZF490J79r/6tnPPXIIC4XGnijwho5NmhZG0XcQeyW5KnT7VmGACFdTHOb9oS5WxZZU29/oZ5Y23rBBoSDX/xZ1LNFiZk6Xfl4ih207jzogv+3nOro93JHQydNeKEwxOtbKqEe7WWJLDw/EzVdJTODrhBYKbjUce10XsavuiTvv+H1Qh4lo2Vx`, 485 expected: `qkFfS3WfLyj3QTQT9i/s57uOPQCTN1jrab8bwxaxyeYUlz2tEtYyKGGUufua8WzdBT2VvWTvH0JkK0LfUJ+vChvcnMFna+tEaCKCFMIOWMLYVZSJDcYMIqaIr8d0Bi2bpbVf5z4WNma0pbCKaXpkYgeg1Sb8HpKG0p0fAez7Q/QRASlvyM5vuIOH8/CM4fF5Ga6aWkTRG0lfxiyeZ2vi3q7uNmsZF490J79r/6tnPPXIIC4XGnijwho5NmhZG0XcQeyW5KnT7VmGACFdTHOb9oS5WxZZU29/oZ5Y23rBBoSDX/xZ1LNFiZk6Xfl4ih207jzogv+3nOro93JHQydNeKEwxOtbKqEe7WWJLDw/EzVdJTODrhBYKbjUce10XsavuiTvv+H1Qh4lo2Vx`, 486 }, 487 test{ 488 in: `O900/Gn82AjyLYqiWZ4ILXBBv/ZaXpTpQL0p9nv7gwF2MWsS2OWEImcVDa+1ElrjUumG6CVEv/rvax53krqJJDg+4Z/XcHxv58w6hNrXiWqFNjxlu5RZHvj1oQQXnS2n8qw8e/c+8ea2TiDIVr4OmgZz1G9uSPBeOZJvySqdgNPMpgfjZwkL2ez9/x31sLuQxi/FW3DFXU6kGSUjaq8g/iGXlaaAcQ0t9Gy+y005Z9wpr2JWWzishL+1JZp9D4SY/r3NHDphN4MNdLHMNBRPSIgfsaSqfLraIt+zWIycsd+nksVxtPv9wcyXy51E1qlHr6Uygz2VZYD9q9zyxEX4wRP2VEewHYUomL9d1F6gGG5fN3z82bQ4hI9uDirWhneWazUOQBRud5otPOm9`, 489 expected: `O900/Gn82AjyLYqiWZ4ILXBBv/ZaXpTpQL0p9nv7gwF2MWsS2OWEImcVDa+1ElrjUumG6CVEv/rvax53krqJJDg+4Z/XcHxv58w6hNrXiWqFNjxlu5RZHvj1oQQXnS2n8qw8e/c+8ea2TiDIVr4OmgZz1G9uSPBeOZJvySqdgNPMpgfjZwkL2ez9/x31sLuQxi/FW3DFXU6kGSUjaq8g/iGXlaaAcQ0t9Gy+y005Z9wpr2JWWzishL+1JZp9D4SY/r3NHDphN4MNdLHMNBRPSIgfsaSqfLraIt+zWIycsd+nksVxtPv9wcyXy51E1qlHr6Uygz2VZYD9q9zyxEX4wRP2VEewHYUomL9d1F6gGG5fN3z82bQ4hI9uDirWhneWazUOQBRud5otPOm9`, 490 }, 491 test{ 492 in: `C3c+d5Q9lyTafPLdelG1TKaLFinw1TOjyI6KkrQyHKkttfnO58WFvScl1TiRcB/iHxKahskoE2+VRLUIhctuDU4sUvQh/g9Arw0LAA4QTxuLFt01XYdigurz4FT15ox2oDGGGrRb3VGjDTXK1OWVJoLMW95EVqyMc9F+Fdej85LHE+8WesIfacjUQtTG1tzYVQTfubZq0+qxXws8QrxMLFtVE38tbeXo+Ok1/U5TUa6FjWflEfvKY3XVcl8RKkXua7fVz/Blj8Gh+dWe2cOxa0lpM75ZHyz9adQrB2Pb4571E4u2xI5un0R0MFJZBQuPDc1G5rPhyk+Hb4LRG3dS0m8IASQUOskv93z978L1+Abu9CLP6d6s5p+BzWxhMUqwQXC/CCpTywrkJ0RG`, 493 expected: `C3c+d5Q9lyTafPLdelG1TKaLFinw1TOjyI6KkrQyHKkttfnO58WFvScl1TiRcB/iHxKahskoE2+VRLUIhctuDU4sUvQh/g9Arw0LAA4QTxuLFt01XYdigurz4FT15ox2oDGGGrRb3VGjDTXK1OWVJoLMW95EVqyMc9F+Fdej85LHE+8WesIfacjUQtTG1tzYVQTfubZq0+qxXws8QrxMLFtVE38tbeXo+Ok1/U5TUa6FjWflEfvKY3XVcl8RKkXua7fVz/Blj8Gh+dWe2cOxa0lpM75ZHyz9adQrB2Pb4571E4u2xI5un0R0MFJZBQuPDc1G5rPhyk+Hb4LRG3dS0m8IASQUOskv93z978L1+Abu9CLP6d6s5p+BzWxhMUqwQXC/CCpTywrkJ0RG`, 494 }, 495 // Basic XSS 496 test{ 497 in: `test<script>alert(document.cookie)</script>`, 498 expected: `test`, 499 }, 500 test{ 501 in: `<<<><<script src=http://fake-evil.ru/test.js>`, 502 expected: `<<<><`, 503 }, 504 test{ 505 in: `<script<script src=http://fake-evil.ru/test.js>>`, 506 expected: `>`, 507 }, 508 test{ 509 in: `<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 510 expected: ``, 511 }, 512 test{ 513 in: "<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", 514 expected: ``, 515 }, 516 test{ 517 in: `<BODY ONLOAD=alert('XSS')>`, 518 expected: ``, 519 }, 520 test{ 521 in: `<iframe src=http://ha.ckers.org/scriptlet.html <`, 522 expected: ``, 523 }, 524 test{ 525 in: `<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');"">`, 526 expected: `<input type="IMAGE">`, 527 }, 528 test{ 529 in: `<a onblur="alert(secret)" href="http://www.google.com">Google</a>`, 530 expected: `<a href="http://www.google.com">Google</a>`, 531 }, 532 // IMG attacks 533 test{ 534 in: `<img src="http://www.myspace.com/img.gif"/>`, 535 expected: `<img src="http://www.myspace.com/img.gif"/>`, 536 }, 537 test{ 538 in: `<img src=javascript:alert(document.cookie)>`, 539 expected: ``, 540 }, 541 test{ 542 in: `<IMG SRC=javascript:alert('XSS')>`, 543 expected: ``, 544 }, 545 test{ 546 in: `<IMG SRC='javascript:alert('XSS')'>`, 547 expected: ``, 548 }, 549 test{ 550 in: `<IMG SRC="jav
ascript:alert('XSS');">`, 551 expected: ``, 552 }, 553 test{ 554 in: `<IMG SRC=javascript:alert('XSS')>`, 555 expected: ``, 556 }, 557 test{ 558 in: `<IMG SRC=javascript:alert('XSS')>`, 559 expected: ``, 560 }, 561 test{ 562 in: `<IMG SRC="javascript:alert('XSS')"`, 563 expected: ``, 564 }, 565 test{ 566 in: `<IMG LOWSRC="javascript:alert('XSS')">`, 567 expected: ``, 568 }, 569 test{ 570 in: `<BGSOUND SRC="javascript:alert('XSS');">`, 571 expected: ``, 572 }, 573 // HREF attacks 574 test{ 575 in: `<LINK REL="stylesheet" HREF="javascript:alert('XSS');">`, 576 expected: ``, 577 }, 578 test{ 579 in: `<LINK REL="stylesheet" HREF="http://ha.ckers.org/xss.css">`, 580 expected: ``, 581 }, 582 test{ 583 in: `<STYLE>@import'http://ha.ckers.org/xss.css';</STYLE>`, 584 expected: ``, 585 }, 586 test{ 587 in: `<STYLE>BODY{-moz-binding:url("http://ha.ckers.org/xssmoz.xml#xss")}</STYLE>`, 588 expected: ``, 589 }, 590 test{ 591 in: `<STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS`, 592 expected: `<ul><li>XSS`, 593 }, 594 test{ 595 in: `<IMG SRC='vbscript:msgbox("XSS")'>`, 596 expected: ``, 597 }, 598 test{ 599 in: `<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert('XSS');">`, 600 expected: ``, 601 }, 602 test{ 603 in: `<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert('XSS');">`, 604 expected: ``, 605 }, 606 test{ 607 in: `<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">`, 608 expected: ``, 609 }, 610 test{ 611 in: `<IFRAME SRC="javascript:alert('XSS');"></IFRAME>`, 612 expected: ``, 613 }, 614 test{ 615 in: `<FRAMESET><FRAME SRC="javascript:alert('XSS');"></FRAMESET>`, 616 expected: ``, 617 }, 618 test{ 619 in: `<TABLE BACKGROUND="javascript:alert('XSS')">`, 620 expected: ``, 621 }, 622 test{ 623 in: `<TABLE><TD BACKGROUND="javascript:alert('XSS')">`, 624 expected: `<td>`, 625 }, 626 test{ 627 in: `<DIV STYLE="background-image: url(javascript:alert('XSS'))">`, 628 expected: `<div>`, 629 }, 630 test{ 631 in: `<DIV STYLE="width: expression(alert('XSS'));">`, 632 expected: `<div>`, 633 }, 634 test{ 635 in: `<IMG STYLE="xss:expr/*XSS*/ession(alert('XSS'))">`, 636 expected: ``, 637 }, 638 test{ 639 in: `<STYLE>@im\\port'\\ja\\vasc\\ript:alert("XSS")';</STYLE>`, 640 expected: ``, 641 }, 642 test{ 643 in: `<BASE HREF="javascript:alert('XSS');//">`, 644 expected: ``, 645 }, 646 test{ 647 in: `<BaSe hReF="http://arbitrary.com/">`, 648 expected: ``, 649 }, 650 test{ 651 in: `<OBJECT TYPE="text/x-scriptlet" DATA="http://ha.ckers.org/scriptlet.html"></OBJECT>`, 652 expected: ``, 653 }, 654 test{ 655 in: `<OBJECT classid=clsid:ae24fdae-03c6-11d1-8b76-0080c744f389><param name=url value=javascript:alert('XSS')></OBJECT>`, 656 expected: ``, 657 }, 658 test{ 659 in: `<EMBED SRC="http://ha.ckers.org/xss.swf" AllowScriptAccess="always"></EMBED>`, 660 expected: ``, 661 }, 662 test{ 663 in: `<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>`, 664 expected: ``, 665 }, 666 test{ 667 in: `<SCRIPT a=">" SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 668 expected: ``, 669 }, 670 test{ 671 in: `<SCRIPT a=">" '' SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 672 expected: ``, 673 }, 674 test{ 675 in: "<SCRIPT a=`>` SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", 676 expected: ``, 677 }, 678 test{ 679 in: `<SCRIPT a=">'>" SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 680 expected: ``, 681 }, 682 test{ 683 in: `<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 684 expected: `PT SRC="http://ha.ckers.org/xss.js">`, 685 }, 686 test{ 687 in: `<SCRIPT SRC=http://ha.ckers.org/xss.js`, 688 expected: ``, 689 }, 690 test{ 691 in: `<div/style=\-\mo\z\-b\i\nd\in\g:\url(//business\i\nfo.co.uk\/labs\/xbl\/xbl\.xml\#xss)&>`, 692 expected: `<div>`, 693 }, 694 test{ 695 in: `<a href='aim: &c:\\windows\\system32\\calc.exe' ini='C:\\Documents and Settings\\All Users\\Start Menu\\Programs\\Startup\\pwnd.bat'>`, 696 expected: ``, 697 }, 698 test{ 699 in: `<!--\n<A href=\n- --><a href=javascript:alert:document.domain>test-->`, 700 expected: `test-->`, 701 }, 702 test{ 703 in: `<a></a style="xx:expr/**/ession(document.appendChild(document.createElement('script')).src='http://h4k.in/i.js')">`, 704 expected: ``, 705 }, 706 // CSS attacks 707 test{ 708 in: `<div style="position:absolute">`, 709 expected: `<div>`, 710 }, 711 test{ 712 in: `<style>b { position:absolute }</style>`, 713 expected: ``, 714 }, 715 test{ 716 in: `<div style="z-index:25">test</div>`, 717 expected: `<div>test</div>`, 718 }, 719 test{ 720 in: `<style>z-index:25</style>`, 721 expected: ``, 722 }, 723 // Strings that cause issues for tokenizers 724 test{ 725 in: `<a - href="http://www.test.com">`, 726 expected: `<a href="http://www.test.com">`, 727 }, 728 // Comments 729 test{ 730 in: `text <!-- comment -->`, 731 expected: `text `, 732 }, 733 test{ 734 in: `<div>text <!-- comment --></div>`, 735 expected: `<div>text </div>`, 736 }, 737 test{ 738 in: `<div>text <!--[if IE]> comment <[endif]--></div>`, 739 expected: `<div>text </div>`, 740 }, 741 test{ 742 in: `<div>text <!--[if IE]> <!--[if gte 6]> comment <[endif]--><[endif]--></div>`, 743 expected: `<div>text <[endif]--></div>`, 744 }, 745 test{ 746 in: `<div>text <!--[if IE]> <!-- IE specific --> comment <[endif]--></div>`, 747 expected: `<div>text comment <[endif]--></div>`, 748 }, 749 test{ 750 in: `<div>text <!-- [ if lte 6 ]>\ncomment <[ endif\n]--></div>`, 751 expected: `<div>text </div>`, 752 }, 753 test{ 754 in: `<div>text <![if !IE]> comment <![endif]></div>`, 755 expected: `<div>text comment </div>`, 756 }, 757 test{ 758 in: `<div>text <![ if !IE]> comment <![endif]></div>`, 759 expected: `<div>text comment </div>`, 760 }, 761 } 762 763 // These tests are run concurrently to enable the race detector to pick up 764 // potential issues 765 wg := sync.WaitGroup{} 766 wg.Add(len(tests)) 767 for ii, tt := range tests { 768 go func(ii int, tt test) { 769 out := p.Sanitize(tt.in) 770 if out != tt.expected { 771 t.Errorf( 772 "test %d failed;\ninput : %s\noutput : %s\nexpected: %s", 773 ii, 774 tt.in, 775 out, 776 tt.expected, 777 ) 778 } 779 wg.Done() 780 }(ii, tt) 781 } 782 wg.Wait() 783 } 784 785 func TestXSS(t *testing.T) { 786 787 p := UGCPolicy() 788 789 tests := []test{ 790 test{ 791 in: `<A HREF="javascript:document.location='http://www.google.com/'">XSS</A>`, 792 expected: `XSS`, 793 }, 794 test{ 795 in: `<A HREF="h 796 tt p://6 6.000146.0x7.147/">XSS</A>`, 797 expected: `XSS`, 798 }, 799 test{ 800 in: `<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 801 expected: `PT SRC="http://ha.ckers.org/xss.js">`, 802 }, 803 test{ 804 in: `<SCRIPT a=">'>" SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 805 expected: ``, 806 }, 807 test{ 808 in: "<SCRIPT a=`>` SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", 809 expected: ``, 810 }, 811 test{ 812 in: `<SCRIPT "a='>'" SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 813 expected: ``, 814 }, 815 test{ 816 in: `<SCRIPT a=">" '' SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 817 expected: ``, 818 }, 819 test{ 820 in: `<SCRIPT =">" SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 821 expected: ``, 822 }, 823 test{ 824 in: `<SCRIPT a=">" SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 825 expected: ``, 826 }, 827 test{ 828 in: `<HEAD><META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=UTF-7"> </HEAD>+ADw-SCRIPT+AD4-alert('XSS')`, 829 expected: ` +ADw-SCRIPT+AD4-alert('XSS')`, 830 }, 831 test{ 832 in: `<META HTTP-EQUIV="Set-Cookie" Content="USERID=<SCRIPT>alert('XSS')</SCRIPT>">`, 833 expected: ``, 834 }, 835 test{ 836 in: `<? echo('<SCR)'; 837 echo('IPT>alert("XSS")</SCRIPT>'); ?>`, 838 expected: `alert("XSS")'); ?>`, 839 }, 840 test{ 841 in: `<!--#exec cmd="/bin/echo '<SCR'"--><!--#exec cmd="/bin/echo 'IPT SRC=http://ha.ckers.org/xss.js></SCRIPT>'"-->`, 842 expected: ``, 843 }, 844 test{ 845 in: `<HTML><BODY> 846 <?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time"> 847 <?import namespace="t" implementation="#default#time2"> 848 <t:set attributeName="innerHTML" to="XSS<SCRIPT DEFER>alert("XSS")</SCRIPT>"> 849 </BODY></HTML>`, 850 expected: "\n\n\n">\n", 851 }, 852 test{ 853 in: `<XML SRC="xsstest.xml" ID=I></XML> 854 <SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>`, 855 expected: ` 856 <span></span>`, 857 }, 858 test{ 859 in: `<XML ID="xss"><I><B><IMG SRC="javas<!-- -->cript:alert('XSS')"></B></I></XML> 860 <SPAN DATASRC="#xss" DATAFLD="B" DATAFORMATAS="HTML"></SPAN>`, 861 expected: `<i><b></b></i> 862 <span></span>`, 863 }, 864 test{ 865 in: `<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>`, 866 expected: ``, 867 }, 868 test{ 869 in: `<OBJECT TYPE="text/x-scriptlet" DATA="http://ha.ckers.org/scriptlet.html"></OBJECT>`, 870 expected: ``, 871 }, 872 test{ 873 in: `<BASE HREF="javascript:alert('XSS');//">`, 874 expected: ``, 875 }, 876 test{ 877 in: `<!--[if gte IE 4]><SCRIPT>alert('XSS');</SCRIPT><![endif]-->`, 878 expected: ``, 879 }, 880 test{ 881 in: `<DIV STYLE="width: expression(alert('XSS'));">`, 882 expected: `<div>`, 883 }, 884 test{ 885 in: `<DIV STYLE="background-image: url(javascript:alert('XSS'))">`, 886 expected: `<div>`, 887 }, 888 test{ 889 in: `<DIV STYLE="background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029">`, 890 expected: `<div>`, 891 }, 892 test{ 893 in: `<DIV STYLE="background-image: url(javascript:alert('XSS'))">`, 894 expected: `<div>`, 895 }, 896 test{ 897 in: `<TABLE><TD BACKGROUND="javascript:alert('XSS')">`, 898 expected: `<table><td>`, 899 }, 900 test{ 901 in: `<TABLE BACKGROUND="javascript:alert('XSS')">`, 902 expected: `<table>`, 903 }, 904 test{ 905 in: `<FRAMESET><FRAME SRC="javascript:alert('XSS');"></FRAMESET>`, 906 expected: ``, 907 }, 908 test{ 909 in: `<IFRAME SRC=# onmouseover="alert(document.cookie)"></IFRAME>`, 910 expected: ``, 911 }, 912 test{ 913 in: `<IFRAME SRC="javascript:alert('XSS');"></IFRAME>`, 914 expected: ``, 915 }, 916 test{ 917 in: `<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert('XSS');">`, 918 expected: ``, 919 }, 920 test{ 921 in: `<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">`, 922 expected: ``, 923 }, 924 test{ 925 in: `<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert('XSS');">`, 926 expected: ``, 927 }, 928 test{ 929 in: `<XSS STYLE="behavior: url(xss.htc);">`, 930 expected: ``, 931 }, 932 test{ 933 in: `<XSS STYLE="xss:expression(alert('XSS'))">`, 934 expected: ``, 935 }, 936 test{ 937 in: `<STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE>`, 938 expected: ``, 939 }, 940 test{ 941 in: `<STYLE>.XSS{background-image:url("javascript:alert('XSS')");}</STYLE><A CLASS=XSS></A>`, 942 expected: ``, 943 }, 944 test{ 945 in: `<STYLE TYPE="text/javascript">alert('XSS');</STYLE>`, 946 expected: ``, 947 }, 948 test{ 949 in: `<IMG STYLE="xss:expr/*XSS*/ession(alert('XSS'))">`, 950 expected: ``, 951 }, 952 test{ 953 in: `<STYLE>@im\port'\ja\vasc\ript:alert("XSS")';</STYLE>`, 954 expected: ``, 955 }, 956 test{ 957 in: `<STYLE>BODY{-moz-binding:url("http://ha.ckers.org/xssmoz.xml#xss")}</STYLE>`, 958 expected: ``, 959 }, 960 test{ 961 in: `<META HTTP-EQUIV="Link" Content="<http://ha.ckers.org/xss.css>; REL=stylesheet">`, 962 expected: ``, 963 }, 964 test{ 965 in: `<STYLE>@import'http://ha.ckers.org/xss.css';</STYLE>`, 966 expected: ``, 967 }, 968 test{ 969 in: `<LINK REL="stylesheet" HREF="http://ha.ckers.org/xss.css">`, 970 expected: ``, 971 }, 972 test{ 973 in: `<LINK REL="stylesheet" HREF="javascript:alert('XSS');">`, 974 expected: ``, 975 }, 976 test{ 977 in: `<BR SIZE="&{alert('XSS')}">`, 978 expected: `<br>`, 979 }, 980 test{ 981 in: `<BGSOUND SRC="javascript:alert('XSS');">`, 982 expected: ``, 983 }, 984 test{ 985 in: `<BODY ONLOAD=alert('XSS')>`, 986 expected: ``, 987 }, 988 test{ 989 in: `<STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS</br>`, 990 expected: `<ul><li>XSS</br>`, 991 }, 992 test{ 993 in: `<IMG LOWSRC="javascript:alert('XSS')">`, 994 expected: ``, 995 }, 996 test{ 997 in: `<IMG DYNSRC="javascript:alert('XSS')">`, 998 expected: ``, 999 }, 1000 test{ 1001 in: `<BODY BACKGROUND="javascript:alert('XSS')">`, 1002 expected: ``, 1003 }, 1004 test{ 1005 in: `<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');">`, 1006 expected: ``, 1007 }, 1008 test{ 1009 in: `</TITLE><SCRIPT>alert("XSS");</SCRIPT>`, 1010 expected: ``, 1011 }, 1012 test{ 1013 in: `\";alert('XSS');//`, 1014 expected: `\";alert('XSS');//`, 1015 }, 1016 test{ 1017 in: `<iframe src=http://ha.ckers.org/scriptlet.html <`, 1018 expected: ``, 1019 }, 1020 test{ 1021 in: `<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >`, 1022 expected: ``, 1023 }, 1024 test{ 1025 in: `<<SCRIPT>alert("XSS");//<</SCRIPT>`, 1026 expected: `<`, 1027 }, 1028 test{ 1029 in: "<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", 1030 expected: ``, 1031 }, 1032 test{ 1033 in: `<SCRIPT/SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 1034 expected: ``, 1035 }, 1036 test{ 1037 in: `<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>`, 1038 expected: ``, 1039 }, 1040 test{ 1041 in: `<IMG SRC="  javascript:alert('XSS');">`, 1042 expected: ``, 1043 }, 1044 test{ 1045 in: `<IMG SRC="jav
ascript:alert('XSS');">`, 1046 expected: `<img src="jav%0Dascript:alert%28%27XSS%27%29;">`, 1047 }, 1048 test{ 1049 in: `<IMG SRC="jav
ascript:alert('XSS');">`, 1050 expected: ``, 1051 }, 1052 test{ 1053 in: `<IMG SRC="jav	ascript:alert('XSS');">`, 1054 expected: ``, 1055 }, 1056 test{ 1057 in: `<IMG SRC="jav ascript:alert('XSS');">`, 1058 expected: ``, 1059 }, 1060 test{ 1061 in: `<IMG SRC=javascript:alert('XSS')>`, 1062 expected: ``, 1063 }, 1064 test{ 1065 in: `<IMG SRC=javascript:a& 1066 #0000108ert('XSS')>`, 1067 expected: ``, 1068 }, 1069 test{ 1070 in: `<IMG SRC=javascript:alert( 1071 'XSS')>`, 1072 expected: ``, 1073 }, 1074 test{ 1075 in: `<IMG SRC=/ onerror="alert(String.fromCharCode(88,83,83))"></img>`, 1076 expected: `<img src="/"></img>`, 1077 }, 1078 test{ 1079 in: `<IMG onmouseover="alert('xxs')">`, 1080 expected: ``, 1081 }, 1082 test{ 1083 in: `<IMG SRC= onmouseover="alert('xxs')">`, 1084 expected: `<img src="onmouseover=%22alert%28%27xxs%27%29%22">`, 1085 }, 1086 test{ 1087 in: `<IMG SRC=# onmouseover="alert('xxs')">`, 1088 expected: ``, 1089 }, 1090 test{ 1091 in: `<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>`, 1092 expected: ``, 1093 }, 1094 test{ 1095 in: `<IMG """><SCRIPT>alert("XSS")</SCRIPT>">`, 1096 expected: `">`, 1097 }, 1098 test{ 1099 in: "<IMG SRC=`javascript:alert(\"RSnake says, 'XSS'\")`>", 1100 expected: `<img src="%60javascript:alert%28%22RSnake">`, 1101 }, 1102 test{ 1103 in: `<IMG SRC=javascript:alert("XSS")>`, 1104 expected: ``, 1105 }, 1106 test{ 1107 in: `<IMG SRC=JaVaScRiPt:alert('XSS')>`, 1108 expected: ``, 1109 }, 1110 test{ 1111 in: `<IMG SRC=javascript:alert('XSS')>`, 1112 expected: ``, 1113 }, 1114 test{ 1115 in: `<IMG SRC="javascript:alert('XSS');">`, 1116 expected: ``, 1117 }, 1118 test{ 1119 in: `<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>`, 1120 expected: ``, 1121 }, 1122 test{ 1123 in: `'';!--"<XSS>=&{()}`, 1124 expected: `'';!--"=&{()}`, 1125 }, 1126 test{ 1127 in: `';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>`, 1128 expected: `';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//-->">'>`, 1129 }, 1130 } 1131 1132 // These tests are run concurrently to enable the race detector to pick up 1133 // potential issues 1134 wg := sync.WaitGroup{} 1135 wg.Add(len(tests)) 1136 for ii, tt := range tests { 1137 go func(ii int, tt test) { 1138 out := p.Sanitize(tt.in) 1139 if out != tt.expected { 1140 t.Errorf( 1141 "test %d failed;\ninput : %s\noutput : %s\nexpected: %s", 1142 ii, 1143 tt.in, 1144 out, 1145 tt.expected, 1146 ) 1147 } 1148 wg.Done() 1149 }(ii, tt) 1150 } 1151 wg.Wait() 1152 } 1153 1154 func TestIssue3(t *testing.T) { 1155 // https://yougam/libraries/microcosm-cc/bluemonday/issues/3 1156 1157 p := UGCPolicy() 1158 p.AllowStyling() 1159 1160 tests := []test{ 1161 test{ 1162 in: `Hello <span class="foo bar bash">there</span> world.`, 1163 expected: `Hello <span class="foo bar bash">there</span> world.`, 1164 }, 1165 test{ 1166 in: `Hello <span class="javascript:alert(123)">there</span> world.`, 1167 expected: `Hello <span>there</span> world.`, 1168 }, 1169 test{ 1170 in: `Hello <span class="><script src="http://hackers.org/XSS.js"></script>">there</span> world.`, 1171 expected: `Hello <span>">there</span> world.`, 1172 }, 1173 test{ 1174 in: `Hello <span class="><script src='http://hackers.org/XSS.js'></script>">there</span> world.`, 1175 expected: `Hello <span>there</span> world.`, 1176 }, 1177 } 1178 1179 wg := sync.WaitGroup{} 1180 wg.Add(len(tests)) 1181 for ii, tt := range tests { 1182 go func(ii int, tt test) { 1183 out := p.Sanitize(tt.in) 1184 if out != tt.expected { 1185 t.Errorf( 1186 "test %d failed;\ninput : %s\noutput : %s\nexpected: %s", 1187 ii, 1188 tt.in, 1189 out, 1190 tt.expected, 1191 ) 1192 } 1193 wg.Done() 1194 }(ii, tt) 1195 } 1196 wg.Wait() 1197 } 1198 1199 func TestIssue9(t *testing.T) { 1200 1201 p := UGCPolicy() 1202 p.AllowAttrs("class").Matching(SpaceSeparatedTokens).OnElements("div", "span") 1203 p.AllowAttrs("class", "name").Matching(SpaceSeparatedTokens).OnElements("a") 1204 p.AllowAttrs("rel").Matching(regexp.MustCompile(`^nofollow$`)).OnElements("a") 1205 p.AllowAttrs("aria-hidden").Matching(regexp.MustCompile(`^true$`)).OnElements("a") 1206 p.AllowDataURIImages() 1207 1208 tt := test{ 1209 in: `<h2><a name="git-diff" class="anchor" href="#git-diff" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>git diff</h2>`, 1210 expected: `<h2><a name="git-diff" class="anchor" href="#git-diff" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>git diff</h2>`, 1211 } 1212 out := p.Sanitize(tt.in) 1213 if out != tt.expected { 1214 t.Errorf( 1215 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1216 tt.in, 1217 out, 1218 tt.expected, 1219 ) 1220 } 1221 1222 tt = test{ 1223 in: `<h2><a name="git-diff" class="anchor" href="#git-diff" aria-hidden="true"><span class="octicon octicon-link"></span></a>git diff</h2>`, 1224 expected: `<h2><a name="git-diff" class="anchor" href="#git-diff" aria-hidden="true" rel="nofollow"><span class="octicon octicon-link"></span></a>git diff</h2>`, 1225 } 1226 out = p.Sanitize(tt.in) 1227 if out != tt.expected { 1228 t.Errorf( 1229 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1230 tt.in, 1231 out, 1232 tt.expected, 1233 ) 1234 } 1235 1236 p.AddTargetBlankToFullyQualifiedLinks(true) 1237 1238 tt = test{ 1239 in: `<h2><a name="git-diff" class="anchor" href="#git-diff" aria-hidden="true"><span class="octicon octicon-link"></span></a>git diff</h2>`, 1240 expected: `<h2><a name="git-diff" class="anchor" href="#git-diff" aria-hidden="true" rel="nofollow"><span class="octicon octicon-link"></span></a>git diff</h2>`, 1241 } 1242 out = p.Sanitize(tt.in) 1243 if out != tt.expected { 1244 t.Errorf( 1245 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1246 tt.in, 1247 out, 1248 tt.expected, 1249 ) 1250 } 1251 1252 tt = test{ 1253 in: `<h2><a name="git-diff" class="anchor" href="https://yougam/libraries/shurcooL/github_flavored_markdown/blob/master/sanitize_test.go" aria-hidden="true"><span class="octicon octicon-link"></span></a>git diff</h2>`, 1254 expected: `<h2><a name="git-diff" class="anchor" href="https://yougam/libraries/shurcooL/github_flavored_markdown/blob/master/sanitize_test.go" aria-hidden="true" rel="nofollow" target="_blank"><span class="octicon octicon-link"></span></a>git diff</h2>`, 1255 } 1256 out = p.Sanitize(tt.in) 1257 if out != tt.expected { 1258 t.Errorf( 1259 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1260 tt.in, 1261 out, 1262 tt.expected, 1263 ) 1264 } 1265 1266 tt = test{ 1267 in: `<h2><a name="git-diff" class="anchor" href="https://yougam/libraries/shurcooL/github_flavored_markdown/blob/master/sanitize_test.go" aria-hidden="true" target="namedwindow"><span class="octicon octicon-link"></span></a>git diff</h2>`, 1268 expected: `<h2><a name="git-diff" class="anchor" href="https://yougam/libraries/shurcooL/github_flavored_markdown/blob/master/sanitize_test.go" aria-hidden="true" rel="nofollow" target="_blank"><span class="octicon octicon-link"></span></a>git diff</h2>`, 1269 } 1270 out = p.Sanitize(tt.in) 1271 if out != tt.expected { 1272 t.Errorf( 1273 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1274 tt.in, 1275 out, 1276 tt.expected, 1277 ) 1278 } 1279 } 1280 1281 func TestIssue18(t *testing.T) { 1282 p := UGCPolicy() 1283 1284 p.AllowAttrs("color").OnElements("font") 1285 p.AllowElements("font") 1286 1287 tt := test{ 1288 in: `<font face="Arial">No link here. <a href="http://link.com">link here</a>.</font> Should not be linked here.`, 1289 expected: `No link here. <a href="http://link.com" rel="nofollow">link here</a>. Should not be linked here.`, 1290 } 1291 out := p.Sanitize(tt.in) 1292 if out != tt.expected { 1293 t.Errorf( 1294 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1295 tt.in, 1296 out, 1297 tt.expected) 1298 } 1299 } 1300 1301 func TestIssue23(t *testing.T) { 1302 p := NewPolicy() 1303 p.SkipElementsContent("tag1", "tag2") 1304 input := `<tag1>cut<tag2></tag2>harm</tag1><tag1>123</tag1><tag2>234</tag2>` 1305 out := p.Sanitize(input) 1306 expected := "" 1307 if out != expected { 1308 t.Errorf( 1309 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1310 input, 1311 out, 1312 expected) 1313 } 1314 1315 p = NewPolicy() 1316 p.SkipElementsContent("tag") 1317 p.AllowElements("p") 1318 input = `<tag>234<p>asd</p></tag>` 1319 out = p.Sanitize(input) 1320 expected = "" 1321 if out != expected { 1322 t.Errorf( 1323 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1324 input, 1325 out, 1326 expected) 1327 } 1328 1329 p = NewPolicy() 1330 p.SkipElementsContent("tag") 1331 p.AllowElements("p", "br") 1332 input = `<tag>234<p>as<br/>d</p></tag>` 1333 out = p.Sanitize(input) 1334 expected = "" 1335 if out != expected { 1336 t.Errorf( 1337 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1338 input, 1339 out, 1340 expected) 1341 } 1342 } 1343 1344 func TestAllowNoAttrs(t *testing.T) { 1345 input := "<tag>test</tag>" 1346 outputFail := "test" 1347 outputOk := input 1348 1349 p := NewPolicy() 1350 p.AllowElements("tag") 1351 1352 if output := p.Sanitize(input); output != outputFail { 1353 t.Errorf( 1354 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1355 input, 1356 output, 1357 outputFail, 1358 ) 1359 } 1360 1361 p.AllowNoAttrs().OnElements("tag") 1362 1363 if output := p.Sanitize(input); output != outputOk { 1364 t.Errorf( 1365 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1366 input, 1367 output, 1368 outputOk, 1369 ) 1370 } 1371 } 1372 1373 func TestSkipElementsContent(t *testing.T) { 1374 input := "<tag>test</tag>" 1375 outputFail := "test" 1376 outputOk := "" 1377 1378 p := NewPolicy() 1379 1380 if output := p.Sanitize(input); output != outputFail { 1381 t.Errorf( 1382 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1383 input, 1384 output, 1385 outputFail, 1386 ) 1387 } 1388 1389 p.SkipElementsContent("tag") 1390 1391 if output := p.Sanitize(input); output != outputOk { 1392 t.Errorf( 1393 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1394 input, 1395 output, 1396 outputOk, 1397 ) 1398 } 1399 } 1400 1401 func TestTagSkipClosingTagNested(t *testing.T) { 1402 input := "<tag1><tag2><tag3>text</tag3></tag2></tag1>" 1403 outputOk := "<tag2>text</tag2>" 1404 1405 p := NewPolicy() 1406 p.AllowElements("tag1", "tag3") 1407 p.AllowNoAttrs().OnElements("tag2") 1408 1409 if output := p.Sanitize(input); output != outputOk { 1410 t.Errorf( 1411 "test failed;\ninput : %s\noutput : %s\nexpected: %s", 1412 input, 1413 output, 1414 outputOk, 1415 ) 1416 } 1417 }