github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/bluemonday/example_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_test
    31  
    32  import (
    33  	"fmt"
    34  	"regexp"
    35  	"strings"
    36  
    37  	"github.com/insionng/yougam/libraries/microcosm-cc/bluemonday"
    38  )
    39  
    40  func Example() {
    41  	// Create a new policy
    42  	p := bluemonday.NewPolicy()
    43  
    44  	// Add elements to a policy without attributes
    45  	p.AllowElements("b", "strong")
    46  
    47  	// Add elements as a virtue of adding an attribute
    48  	p.AllowAttrs("nowrap").OnElements("td", "th")
    49  
    50  	// Attributes can either be added to all elements
    51  	p.AllowAttrs("dir").Globally()
    52  
    53  	//Or attributes can be added to specific elements
    54  	p.AllowAttrs("value").OnElements("li")
    55  
    56  	// It is ALWAYS recommended that an attribute be made to match a pattern
    57  	// XSS in HTML attributes is a very easy attack vector
    58  
    59  	// \p{L} matches unicode letters, \p{N} matches unicode numbers
    60  	p.AllowAttrs("title").Matching(regexp.MustCompile(`[\p{L}\p{N}\s\-_',:\[\]!\./\\\(\)&]*`)).Globally()
    61  
    62  	// You can stop at any time and call .Sanitize()
    63  
    64  	// Assumes that string htmlIn was passed in from a HTTP POST and contains
    65  	// untrusted user generated content
    66  	htmlIn := `untrusted user generated content <body onload="alert('XSS')">`
    67  	fmt.Println(p.Sanitize(htmlIn))
    68  
    69  	// And you can take any existing policy and extend it
    70  	p = bluemonday.UGCPolicy()
    71  	p.AllowElements("fieldset", "select", "option")
    72  
    73  	// Links are complex beasts and one of the biggest attack vectors for
    74  	// malicious content so we have included features specifically to help here.
    75  
    76  	// This is not recommended:
    77  	p = bluemonday.NewPolicy()
    78  	p.AllowAttrs("href").Matching(regexp.MustCompile(`(?i)mailto|https?`)).OnElements("a")
    79  
    80  	// The regexp is insufficient in this case to have prevented a malformed
    81  	// value doing something unexpected.
    82  
    83  	// This will ensure that URLs are not considered invalid by Go's net/url
    84  	// package.
    85  	p.RequireParseableURLs(true)
    86  
    87  	// If you have enabled parseable URLs then the following option will allow
    88  	// relative URLs. By default this is disabled and will prevent all local and
    89  	// schema relative URLs (i.e. `href="//www.google.com"` is schema relative).
    90  	p.AllowRelativeURLs(true)
    91  
    92  	// If you have enabled parseable URLs then you can whitelist the schemas
    93  	// that are permitted. Bear in mind that allowing relative URLs in the above
    94  	// option allows for blank schemas.
    95  	p.AllowURLSchemes("mailto", "http", "https")
    96  
    97  	// Regardless of whether you have enabled parseable URLs, you can force all
    98  	// URLs to have a rel="nofollow" attribute. This will be added if it does
    99  	// not exist.
   100  
   101  	// This applies to "a" "area" "link" elements that have a "href" attribute
   102  	p.RequireNoFollowOnLinks(true)
   103  
   104  	// We provide a convenience function that applies all of the above, but you
   105  	// will still need to whitelist the linkable elements:
   106  	p = bluemonday.NewPolicy()
   107  	p.AllowStandardURLs()
   108  	p.AllowAttrs("cite").OnElements("blockquote")
   109  	p.AllowAttrs("href").OnElements("a", "area")
   110  	p.AllowAttrs("src").OnElements("img")
   111  
   112  	// Policy Building Helpers
   113  
   114  	// If you've got this far and you're bored already, we also bundle some
   115  	// other convenience functions
   116  	p = bluemonday.NewPolicy()
   117  	p.AllowStandardAttributes()
   118  	p.AllowImages()
   119  	p.AllowLists()
   120  	p.AllowTables()
   121  }
   122  
   123  func ExampleNewPolicy() {
   124  	// NewPolicy is a blank policy and we need to explicitly whitelist anything
   125  	// that we wish to allow through
   126  	p := bluemonday.NewPolicy()
   127  
   128  	// We ensure any URLs are parseable and have rel="nofollow" where applicable
   129  	p.AllowStandardURLs()
   130  
   131  	// AllowStandardURLs already ensures that the href will be valid, and so we
   132  	// can skip the .Matching()
   133  	p.AllowAttrs("href").OnElements("a")
   134  
   135  	// We allow paragraphs too
   136  	p.AllowElements("p")
   137  
   138  	html := p.Sanitize(
   139  		`<p><a onblur="alert(secret)" href="http://www.google.com">Google</a></p>`,
   140  	)
   141  
   142  	fmt.Println(html)
   143  
   144  	// Output:
   145  	//<p><a href="http://www.google.com" rel="nofollow">Google</a></p>
   146  }
   147  
   148  func ExampleStrictPolicy() {
   149  	// StrictPolicy is equivalent to NewPolicy and as nothing else is declared
   150  	// we are stripping all elements (and their attributes)
   151  	p := bluemonday.StrictPolicy()
   152  
   153  	html := p.Sanitize(
   154  		`Goodbye <a onblur="alert(secret)" href="http://en.wikipedia.org/wiki/Goodbye_Cruel_World_(Pink_Floyd_song)">Cruel</a> World`,
   155  	)
   156  
   157  	fmt.Println(html)
   158  
   159  	// Output:
   160  	//Goodbye Cruel World
   161  }
   162  
   163  func ExampleUGCPolicy() {
   164  	// UGCPolicy is a convenience policy for user generated content.
   165  	p := bluemonday.UGCPolicy()
   166  
   167  	html := p.Sanitize(
   168  		`<a onblur="alert(secret)" href="http://www.google.com">Google</a>`,
   169  	)
   170  
   171  	fmt.Println(html)
   172  
   173  	// Output:
   174  	//<a href="http://www.google.com" rel="nofollow">Google</a>
   175  }
   176  
   177  func ExamplePolicy_AllowAttrs() {
   178  	p := bluemonday.NewPolicy()
   179  
   180  	// Allow the 'title' attribute on every HTML element that has been
   181  	// whitelisted
   182  	p.AllowAttrs("title").Matching(bluemonday.Paragraph).Globally()
   183  
   184  	// Allow the 'abbr' attribute on only the 'td' and 'th' elements.
   185  	p.AllowAttrs("abbr").Matching(bluemonday.Paragraph).OnElements("td", "th")
   186  
   187  	// Allow the 'colspan' and 'rowspan' attributes, matching a positive integer
   188  	// pattern, on only the 'td' and 'th' elements.
   189  	p.AllowAttrs("colspan", "rowspan").Matching(
   190  		bluemonday.Integer,
   191  	).OnElements("td", "th")
   192  }
   193  
   194  func ExamplePolicy_AllowElements() {
   195  	p := bluemonday.NewPolicy()
   196  
   197  	// Allow styling elements without attributes
   198  	p.AllowElements("br", "div", "hr", "p", "span")
   199  }
   200  
   201  func ExamplePolicy_Sanitize() {
   202  	// UGCPolicy is a convenience policy for user generated content.
   203  	p := bluemonday.UGCPolicy()
   204  
   205  	// string in, string out
   206  	html := p.Sanitize(`<a onblur="alert(secret)" href="http://www.google.com">Google</a>`)
   207  
   208  	fmt.Println(html)
   209  
   210  	// Output:
   211  	//<a href="http://www.google.com" rel="nofollow">Google</a>
   212  }
   213  
   214  func ExamplePolicy_SanitizeBytes() {
   215  	// UGCPolicy is a convenience policy for user generated content.
   216  	p := bluemonday.UGCPolicy()
   217  
   218  	// []byte in, []byte out
   219  	b := []byte(`<a onblur="alert(secret)" href="http://www.google.com">Google</a>`)
   220  	b = p.SanitizeBytes(b)
   221  
   222  	fmt.Println(string(b))
   223  
   224  	// Output:
   225  	//<a href="http://www.google.com" rel="nofollow">Google</a>
   226  }
   227  
   228  func ExamplePolicy_SanitizeReader() {
   229  	// UGCPolicy is a convenience policy for user generated content.
   230  	p := bluemonday.UGCPolicy()
   231  
   232  	// io.Reader in, bytes.Buffer out
   233  	r := strings.NewReader(`<a onblur="alert(secret)" href="http://www.google.com">Google</a>`)
   234  	buf := p.SanitizeReader(r)
   235  
   236  	fmt.Println(buf.String())
   237  
   238  	// Output:
   239  	//<a href="http://www.google.com" rel="nofollow">Google</a>
   240  }