1d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// Copyright (c) 2011, Mike Samuel
2d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// All rights reserved.
3d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel//
4d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// Redistribution and use in source and binary forms, with or without
5d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// modification, are permitted provided that the following conditions
6d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// are met:
7d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel//
8d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// Redistributions of source code must retain the above copyright
9d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// notice, this list of conditions and the following disclaimer.
10d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// Redistributions in binary form must reproduce the above copyright
11d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// notice, this list of conditions and the following disclaimer in the
12d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// documentation and/or other materials provided with the distribution.
13d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// Neither the name of the OWASP nor the names of its contributors may
14d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// be used to endorse or promote products derived from this software
15d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// without specific prior written permission.
16d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel// POSSIBILITY OF SUCH DAMAGE.
28d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel
29d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuelpackage org.owasp.html;
30d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel
31d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuelimport java.io.ByteArrayInputStream;
32d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuelimport java.io.ByteArrayOutputStream;
33d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuelimport java.io.InputStream;
34d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuelimport java.io.PrintStream;
35d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuelimport java.lang.reflect.Method;
36d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel
37d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuelimport com.google.common.base.Throwables;
38d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel
39be666032a113a8af92bc557add8e83579cf0ef5cmikesamuelimport org.junit.Test;
406ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuelimport org.owasp.html.examples.EbayPolicyExample;
416ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel
42d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuelimport junit.framework.TestCase;
43d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel
44d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuelpublic class ExamplesTest extends TestCase {
45be666032a113a8af92bc557add8e83579cf0ef5cmikesamuel  @Test
46be666032a113a8af92bc557add8e83579cf0ef5cmikesamuel  public static final void testExamplesRun() throws Exception {
47d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel    InputStream stdin = System.in;
48d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel    PrintStream stdout = System.out;
49d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel    PrintStream stderr = System.err;
506f71b09d7575db927c132c916484b0570420f30dmikesamuel    for (Class<?> exampleClass : AllExamples.CLASSES) {
51d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel      InputStream emptyIn = new ByteArrayInputStream(new byte[0]);
52d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel      ByteArrayOutputStream captured = new ByteArrayOutputStream();
53d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel      PrintStream capturingOut = new PrintStream(captured, true, "UTF-8");
54d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel      System.setIn(emptyIn);
55d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel      System.setOut(capturingOut);
56d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel      System.setErr(capturingOut);
57d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel
58d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel      Method main;
59d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel      try {
60d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel        main = exampleClass.getDeclaredMethod("main", String[].class);
61d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel        // Invoke with no arguments to sanitize empty input stream to output.
62d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel        main.invoke(null, new Object[] { new String[0] });
63d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel      } catch (Exception ex) {
64d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel        capturingOut.flush();
65d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel        System.err.println(
666f71b09d7575db927c132c916484b0570420f30dmikesamuel            "Example " + exampleClass.getSimpleName() + "\n"
676f71b09d7575db927c132c916484b0570420f30dmikesamuel            + captured.toString("UTF-8"));
68d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel        Throwables.propagate(ex);
69d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel      } finally {
70d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel        System.setIn(stdin);
71d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel        System.setOut(stdout);
72d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel        System.setErr(stderr);
73d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel      }
74d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel    }
75d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel  }
766ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel
77be666032a113a8af92bc557add8e83579cf0ef5cmikesamuel  @Test
78be666032a113a8af92bc557add8e83579cf0ef5cmikesamuel  public static final void testSanitizeRemovesScripts() {
796ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel    String input =
806ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel      "<p>Hello World</p>"
816ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel      + "<script language=\"text/javascript\">alert(\"bad\");</script>";
826ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel    String sanitized = EbayPolicyExample.POLICY_DEFINITION.sanitize(input);
836ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel    assertEquals("<p>Hello World</p>", sanitized);
846ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel  }
85be666032a113a8af92bc557add8e83579cf0ef5cmikesamuel
86be666032a113a8af92bc557add8e83579cf0ef5cmikesamuel  @Test
87be666032a113a8af92bc557add8e83579cf0ef5cmikesamuel  public static final void testSanitizeRemovesOnclick() {
886ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel    String input = "<p onclick=\"alert(\"bad\");\">Hello World</p>";
896ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel    String sanitized = EbayPolicyExample.POLICY_DEFINITION.sanitize(input);
906ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel    assertEquals("<p>Hello World</p>", sanitized);
916ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel  }
926ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel
93be666032a113a8af92bc557add8e83579cf0ef5cmikesamuel  @Test
94be666032a113a8af92bc557add8e83579cf0ef5cmikesamuel  public static final void testTextAllowedInLinks() {
956ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel    String input = "<a href=\"../good.html\">click here</a>";
966ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel    String sanitized = EbayPolicyExample.POLICY_DEFINITION.sanitize(input);
976ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel    assertEquals("<a href=\"../good.html\" rel=\"nofollow\">click here</a>",
986ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel                 sanitized);
996ca215a0c4ddbbf4f6528df5d0e6ba2009d564cdmikesamuel  }
100d702e7e7fd237420e6b22b93a02ec5996c88d2eamikesamuel}
101