3
import com.google.common.base.Predicate;
4
import com.google.common.base.Throwables;
5
import org.owasp.html.Handler;
6
import org.owasp.html.HtmlSanitizer;
7
import org.owasp.html.HtmlStreamRenderer;
8
import org.owasp.html.PolicyFactory;
10
import java.io.IOException;
11
import java.util.regex.Pattern;
14
* Policy definition based on OWASP AntiSamy MySpace policy.
16
* @author Kohsuke Kawaguchi
17
* @see <a href="https://www.owasp.org/index.php/Category:OWASP_AntiSamy_Project#Stage_2_-_Choosing_a_base_policy_file">OWASP AntiSamy MySpace Policy</a>
19
public class MyspacePolicy {
20
public static final PolicyFactory POLICY_DEFINITION;
22
private static final Pattern ONSITE_URL = Pattern.compile(
23
"(?:[\\p{L}\\p{N}\\\\\\.\\#@\\$%\\+&;\\-_~,\\?=/!]+|\\#(\\w)+)");
24
private static final Pattern OFFSITE_URL = Pattern.compile(
25
"\\s*(?:(?:ht|f)tps?://|mailto:)[\\p{L}\\p{N}]"
26
+ "[\\p{L}\\p{N}\\p{Zs}\\.\\#@\\$%\\+&;:\\-_~,\\?=/!\\(\\)]*\\s*");
28
private static final Predicate<String> ONSITE_OR_OFFSITE_URL
29
= new Predicate<String>() {
30
public boolean apply(String s) {
31
return ONSITE_URL.matcher(s).matches()
32
|| OFFSITE_URL.matcher(s).matches();
37
POLICY_DEFINITION = new HtmlPolicyBuilder2() {{
38
allowAttributes("id","class","lang","title",
39
"alt","style","media","href","name","shape",
40
"border","cellpadding","cellspacing","colspan","rowspan",
41
"background","bgcolor","abbr","headers","charoff","char",
42
"aixs","nowrap","width","height","align","valign","scope",
43
"tabindex","disabled","readonly","accesskey","size",
44
"autocomplete","rows","cols").globally();
47
// I'm allowing iframe
48
"script","noscript",/*"iframe",*/"frameset","frame");
51
tag("form", "action",ONSITE_OR_OFFSITE_URL,
53
tag("button", "value", "type");
54
tag("input", "maxlength","checked",
55
"src",ONSITE_OR_OFFSITE_URL,
58
tag("select", "multiple");
59
tag("option", "value","label","selected");
61
tag("h1,h2,h3,h4,h5,h6,p,i,b,u,strong,em,small,big,pre,code,cite,samp,sub,sup,strike,center,blockquote");
63
tag("font", "color", "face", "size");
64
tag("a", "nohref","rel");
67
tag("img", "src",ONSITE_OR_OFFSITE_URL,
70
tag("link", "type","rel");
71
tag("ul,ol,li,dd,dl,dt,thead,tbody,tfoot");
72
tag("table", "noresize");
74
tag("colgroup", "span");
76
tag("fieldset,legend");
77
allowStandardUrlProtocols();
81
public static void main(String[] args) throws IOException {
82
// Fetch the HTML to sanitize.
83
String html = "<a href='http://www.google.com/'>Google</a><img src='http://www.yahoo.com'>";
84
// Set up an output channel to receive the sanitized HTML.
85
HtmlStreamRenderer renderer = HtmlStreamRenderer.create(
87
// Receives notifications on a failure to write to the output.
88
new Handler<IOException>() {
89
public void handle(IOException ex) {
90
Throwables.propagate(ex); // System.out suppresses IOExceptions
93
// Our HTML parser is very lenient, but this receives notifications on
94
// truly bizarre inputs.
95
new Handler<String>() {
96
public void handle(String x) {
97
throw new AssertionError(x);
101
// Use the policy defined above to sanitize the HTML.
102
HtmlSanitizer.sanitize(html, POLICY_DEFINITION.apply(renderer));