Home | History | Annotate | Download | only in html
      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 
     29 package org.owasp.html;
     30 
     31 /**
     32  * Pre-packaged HTML sanitizer policies.
     33  *
     34  * <p>
     35  * These policies can be used to sanitize content.
     36  * </p>
     37  * <pre>
     38  *   Sanitizers.FORMATTING.sanitize({@code "<b>Hello, World!</b>"})
     39  * </pre>
     40  * and can be chained
     41  * <pre>
     42  *   PolicyFactory sanitizer = Sanitizers.FORMATTING.and(Sanitizers.BLOCKS);
     43  *   System.out.println(sanitizer.sanitize({@code "<p>Hello, <b>World!</b>"}));
     44  * </pre>
     45  *
     46  * <p>
     47  * For more fine-grained control over sanitization, use
     48  * {@link HtmlPolicyBuilder}.
     49  * </p>
     50  *
     51  * @author Mike Samuel <mikesamuel (at) gmail.com>
     52  */
     53 public final class Sanitizers {
     54 
     55   /**
     56    * Allows common formatting elements including {@code <b>}, {@code <i>}, etc.
     57    */
     58   public static final PolicyFactory FORMATTING = new HtmlPolicyBuilder()
     59       .allowCommonInlineFormattingElements().toFactory();
     60 
     61   /**
     62    * Allows common block elements including <code>&lt;p&gt;</code>,
     63    * <code>&lt;h1&gt;</code>, etc.
     64    */
     65   public static final PolicyFactory BLOCKS = new HtmlPolicyBuilder()
     66       .allowCommonBlockElements().toFactory();
     67 
     68   /**
     69    * Allows certain safe CSS properties in {@code style="..."} attributes.
     70    */
     71   public static final PolicyFactory STYLES = new HtmlPolicyBuilder()
     72       .allowStyling().toFactory();
     73 
     74   /**
     75    * Allows HTTP, HTTPS, MAILTO, and relative links.
     76    */
     77   public static final PolicyFactory LINKS = new HtmlPolicyBuilder()
     78       .allowStandardUrlProtocols().allowElements("a")
     79       .allowAttributes("href").onElements("a").requireRelNofollowOnLinks()
     80       .toFactory();
     81 
     82   private static final AttributePolicy INTEGER = new AttributePolicy() {
     83     public String apply(
     84         String elementName, String attributeName, String value) {
     85       int n = value.length();
     86       if (n == 0) { return null; }
     87       for (int i = 0; i < n; ++i) {
     88         char ch = value.charAt(i);
     89         if (ch == '.') {
     90           if (i == 0) { return null; }
     91           return value.substring(0, i);  // truncate to integer.
     92         } else if (!('0' <= ch && ch <= '9')) {
     93           return null;
     94         }
     95       }
     96       return value;
     97     }
     98   };
     99 
    100   /**
    101    * Allows {@code <img>} elements from HTTP, HTTPS, and relative sources.
    102    */
    103   public static final PolicyFactory IMAGES = new HtmlPolicyBuilder()
    104       .allowUrlProtocols("http", "https").allowElements("img")
    105       .allowAttributes("alt", "src").onElements("img")
    106       .allowAttributes("border", "height", "width").matching(INTEGER)
    107           .onElements("img")
    108       .toFactory();
    109 
    110   private Sanitizers() {
    111     // Uninstantiable.
    112   }
    113 }
    114