xss-sanitize (empty) → 0.1
raw patch · 4 files changed
+145/−0 lines, 4 filesdep +basedep +containersdep +networksetup-changed
Dependencies added: base, containers, network, tagsoup, utf8-string
Files
- LICENSE +25/−0
- Setup.lhs +7/−0
- Text/HTML/SanitizeXSS.hs +88/−0
- xss-sanitize.cabal +25/−0
+ LICENSE view
@@ -0,0 +1,25 @@+The following license covers this documentation, and the source code, except+where otherwise indicated.++Copyright 2010, Michael Snoyman. All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice, this+ list of conditions and the following disclaimer.++* Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO+EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.lhs view
@@ -0,0 +1,7 @@+#!/usr/bin/env runhaskell++> module Main where+> import Distribution.Simple++> main :: IO ()+> main = defaultMain
+ Text/HTML/SanitizeXSS.hs view
@@ -0,0 +1,88 @@+module Text.HTML.SanitizeXSS (sanitizeXSS) where++import Text.HTML.TagSoup++import Data.Set (Set(), member, fromList)+import Data.Char ( toLower )++import Network.URI ( parseURIReference, URI (..),+ isAllowedInURI, escapeURIString, uriScheme )+import Codec.Binary.UTF8.String ( encodeString )++sanitizeXSS :: String -> String+sanitizeXSS = renderTagsOptions renderOptions {+ optMinimize = \x -> x `elem` ["br","img"] -- <img><img> converts to <img />, <a/> converts to <a></a>+ } . safeTags . parseTags+ where+ safeTags :: [Tag String] -> [Tag String]+ safeTags [] = []+ safeTags (t@(TagClose name):tags) | safeTagName name = t:(safeTags tags)+ | otherwise = safeTags tags+ safeTags (TagOpen name attributes:tags)+ | safeTagName name = TagOpen name (filter safeAttribute attributes) : safeTags tags+ | otherwise = safeTags tags+ safeTags (t:tags) = t:safeTags tags++safeTagName :: String -> Bool+safeTagName tagname = tagname `member` sanitaryTags++safeAttribute :: (String, String) -> Bool+safeAttribute (name, value) = name `member` sanitaryAttributes &&+ (name `notElem` ["href","src"] || sanitaryURI value)+ ++-- | Returns @True@ if the specified URI is not a potential security risk.+sanitaryURI :: String -> Bool+sanitaryURI u =+ case parseURIReference (escapeURI u) of+ Just p -> (map toLower $ uriScheme p) `member` safeURISchemes+ Nothing -> False+++-- | Escape unicode characters in a URI. Characters that are+-- already valid in a URI, including % and ?, are left alone.+escapeURI :: String -> String+escapeURI = escapeURIString isAllowedInURI . encodeString+++safeURISchemes :: Set String+safeURISchemes = fromList [ "", "http:", "https:", "ftp:", "mailto:", "file:",+ "telnet:", "gopher:", "aaa:", "aaas:", "acap:", "cap:", "cid:",+ "crid:", "dav:", "dict:", "dns:", "fax:", "go:", "h323:", "im:",+ "imap:", "ldap:", "mid:", "news:", "nfs:", "nntp:", "pop:",+ "pres:", "sip:", "sips:", "snmp:", "tel:", "urn:", "wais:",+ "xmpp:", "z39.50r:", "z39.50s:", "aim:", "callto:", "cvs:",+ "ed2k:", "feed:", "fish:", "gg:", "irc:", "ircs:", "lastfm:",+ "ldaps:", "magnet:", "mms:", "msnim:", "notes:", "rsync:",+ "secondlife:", "skype:", "ssh:", "sftp:", "smb:", "sms:",+ "snews:", "webcal:", "ymsgr:"]++sanitaryTags :: Set String+sanitaryTags = fromList ["a", "abbr", "acronym", "address", "area", "b", "big",+ "blockquote", "br", "button", "caption", "center",+ "cite", "code", "col", "colgroup", "dd", "del", "dfn",+ "dir", "div", "dl", "dt", "em", "fieldset", "font",+ "form", "h1", "h2", "h3", "h4", "h5", "h6", "hr",+ "i", "img", "input", "ins", "kbd", "label", "legend",+ "li", "map", "menu", "ol", "optgroup", "option", "p",+ "pre", "q", "s", "samp", "select", "small", "span",+ "strike", "strong", "sub", "sup", "table", "tbody",+ "td", "textarea", "tfoot", "th", "thead", "tr", "tt",+ "u", "ul", "var"]++sanitaryAttributes :: Set String+sanitaryAttributes = fromList ["abbr", "accept", "accept-charset",+ "accesskey", "action", "align", "alt", "axis",+ "border", "cellpadding", "cellspacing", "char",+ "charoff", "charset", "checked", "cite", "class",+ "clear", "cols", "colspan", "color", "compact",+ "coords", "datetime", "dir", "disabled",+ "enctype", "for", "frame", "headers", "height",+ "href", "hreflang", "hspace", "id", "ismap",+ "label", "lang", "longdesc", "maxlength", "media",+ "method", "multiple", "name", "nohref", "noshade",+ "nowrap", "prompt", "readonly", "rel", "rev",+ "rows", "rowspan", "rules", "scope", "selected",+ "shape", "size", "span", "src", "start",+ "summary", "tabindex", "target", "title", "type",+ "usemap", "valign", "value", "vspace", "width"]
+ xss-sanitize.cabal view
@@ -0,0 +1,25 @@+name: xss-sanitize+version: 0.1+license: BSD3+license-file: LICENSE+author: Greg Weber <greg@gregweber.info>+maintainer: Greg Weber <greg@gregweber.info>+synopsis: sanitize untrusted HTML to prevent XSS attacks+description: sanitize untrusted HTML to prevent XSS attacks with Text.HTML.SanitizeXSS.sanitizeXSS. see README.md for more details++category: Text.HTML+stability: Stable+cabal-version: >= 1.6 +build-type: Simple+homepage: http://github.com/gregwebs/haskell-xss-sanitize++library+ build-depends: base == 4.*, containers,+ tagsoup >= 0.11, utf8-string >= 0.3, network >= 2++ exposed-modules: Text.HTML.SanitizeXSS+ ghc-options: -Wall++source-repository head+ type: git + location: http://github.com/gregwebs/haskell-xss-sanitize.git