yesod-csp 0.2.6.0 → 0.2.7.0
raw patch · 5 files changed
+59/−5 lines, 5 filesdep +mimePVP ok
version bump matches the API change (PVP)
Dependencies added: mime
API changes (from Hackage documentation)
+ Yesod.Csp: BaseUri :: EscapedURI -> Directive
+ Yesod.Csp: ChildSrc :: SourceList -> Directive
+ Yesod.Csp: FormAction :: SourceList -> Directive
+ Yesod.Csp: PluginTypes :: MimeTypeList -> Directive
+ Yesod.Csp: instance Data.Data.Data Codec.MIME.Type.MIMEParam
+ Yesod.Csp: instance Data.Data.Data Codec.MIME.Type.MIMEType
+ Yesod.Csp: instance Data.Data.Data Codec.MIME.Type.Multipart
+ Yesod.Csp: instance Data.Data.Data Codec.MIME.Type.Type
+ Yesod.Csp.TH: pluginTypes :: Parser Directive
Files
- CHANGELOG.md +4/−0
- src/Yesod/Csp.hs +22/−3
- src/Yesod/Csp/TH.hs +25/−1
- test/Test.hs +5/−0
- yesod-csp.cabal +3/−1
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Changelog +## Version 0.2.7.0+++ Add support for remaining CSP Level 2 directives (see https://github.com/pSub/yesod-csp/pull/5)+ ## Version 0.2.6.0 + Fixes compilation failure with ghc-9.0.2 or newer (see https://github.com/bobjflong/yesod-csp/issues/8)
src/Yesod/Csp.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE OverloadedStrings #-} -- | Add <http://content-security-policy.com/ CSP> headers to Yesod apps.@@ -18,6 +19,7 @@ , textSource ) where +import Codec.MIME.Type as Mime import qualified Data.CaseInsensitive as CI import Data.Data (Data) import Data.List.NonEmpty@@ -140,6 +142,12 @@ textSource (MetaSource _) = "" textSource (Nonce x) = (T.pack . show) x +deriving instance Data Multipart+deriving instance Data Mime.MIMEType+deriving instance Data Mime.MIMEParam+deriving instance Data Mime.Type+type MimeTypeList = NonEmpty Mime.Type+ -- | A list of restrictions to apply. type DirectiveList = [Directive] @@ -154,11 +162,18 @@ | ObjectSrc SourceList | MediaSrc SourceList | FrameSrc SourceList- | FrameAncestors SourceList -- | Applies a sandbox to the result. <http://content-security-policy.com/ See here> for more info. | Sandbox [SandboxOptions]- | ReportUri EscapedURI deriving (Eq, Show, Data, Typeable)+ | ReportUri EscapedURI+ -- | CSP level 2 directives+ | FrameAncestors SourceList+ | ChildSrc SourceList+ | FormAction SourceList+ | BaseUri EscapedURI+ | PluginTypes MimeTypeList+ deriving (Eq, Show, Data, Typeable) + -- | Configuration options for the sandbox. data SandboxOptions = AllowForms | AllowScripts@@ -175,7 +190,6 @@ textDirective (ObjectSrc x) = w "object-src" x textDirective (MediaSrc x) = w "media-src" x textDirective (FrameSrc x) = w "frame-src" x-textDirective (FrameAncestors x) = w "frame-ancestors" x textDirective (ReportUri t) = mconcat ["report-uri ", (T.pack . show) t] textDirective (Sandbox []) = "sandbox" textDirective (Sandbox s) = mconcat ["sandbox ", T.unwords . fmap textSandbox $ s]@@ -183,3 +197,8 @@ textSandbox AllowScripts = "allow-scripts" textSandbox AllowSameOrigin = "allow-same-origin" textSandbox AllowTopNavigation = "allow-top-navigation"+textDirective (FrameAncestors x) = w "frame-ancestors" x+textDirective (ChildSrc x) = w "child-src" x+textDirective (FormAction x) = w "form-action" x+textDirective (BaseUri t) = mconcat ["base-uri ", (T.pack . show) t]+textDirective (PluginTypes t) = mconcat ["plugin-types ", (T.unwords . fmap Mime.showType . toList) t]
src/Yesod/Csp/TH.hs view
@@ -4,12 +4,14 @@ source , withSourceList , reportUri+ , pluginTypes , sandbox , sandboxOptions , directive , csp ) where +import Codec.MIME.Parse (parseMIMEType) import Control.Applicative import Data.Attoparsec.Text import Data.Generics@@ -106,6 +108,8 @@ <|> mediaSrc <|> frameSrc <|> frameAncestors+ <|> childSrc+ <|> formAction where defaultSrc = d "default-src" DefaultSrc scriptSrc = d "script-src" ScriptSrc styleSrc = d "style-src" StyleSrc@@ -116,6 +120,8 @@ mediaSrc = d "media-src" MediaSrc frameSrc = d "frame-src" FrameSrc frameAncestors = d "frame-ancestors" FrameAncestors+ childSrc = d "child-src" ChildSrc+ formAction = d "form-action" FormAction d x y = string x >> s >> slist >>= mkWithSource y slist = sepBy1 source (char ' ') s = spaces@@ -132,6 +138,24 @@ Nothing -> fail "reportUri" -- n.b. compile time error Just uri -> return $ ReportUri uri +baseUri :: Parser Directive+baseUri = do+ _ <- string "base-uri"+ _ <- spaces+ u <- takeTill separated+ case escapeAndParseURI u of+ Nothing -> fail "baseUri" -- n.b. compile time error+ Just uri -> return $ BaseUri uri++pluginTypes :: Parser Directive+pluginTypes = do+ _ <- string "plugin-types"+ _ <- spaces+ u <- takeTill separated+ case parseMIMEType u of+ Nothing -> fail "plugin-types" -- n.b. compile time error+ Just mimeType -> return $ PluginTypes $ pure mimeType+ sandbox :: Parser Directive sandbox = do _ <- string "sandbox"@@ -155,4 +179,4 @@ directive :: Parser DirectiveList directive = sepBy (spaces *> d) separator <* (spaces *> endOfInput)- where d = withSourceList <|> reportUri <|> sandbox+ where d = withSourceList <|> reportUri <|> baseUri <|> pluginTypes <|> sandbox
test/Test.hs view
@@ -4,6 +4,7 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} +import Codec.MIME.Parse (parseMIMEType) import Data.Attoparsec.Text import Data.Functor ((<$>)) import Data.List.NonEmpty@@ -57,6 +58,10 @@ yit "enforces nones" $ do let header = getCspPolicy [ScriptSrc (None :| [Https])] assertEq "none should be alone" header "script-src 'none'"+ yit "works with plugin-types" $ do+ let dom = pure $ fromJust $ parseMIMEType "text/plain"+ header = getCspPolicy [PluginTypes dom]+ assertEq "plugin-types" header "plugin-types text/plain" ydescribe "Headers" $ yit "get set" $ do get HomeR
yesod-csp.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: yesod-csp-version: 0.2.6.0+version: 0.2.7.0 synopsis: Add CSP headers to Yesod apps description: Add CSP headers to Yesod apps. This helps reduce exposure to XSS attacks and bad assets. license: MIT@@ -35,6 +35,7 @@ , syb >= 0.7.2 && < 0.8 , wai >= 3.2.3 && < 3.3 , case-insensitive >= 1.2.1 && < 1.3+ , mime >= 0.4.0.0 && < 0.5 hs-source-dirs: src default-language: Haskell2010 ghc-options: -Wall@@ -53,4 +54,5 @@ , network-uri , attoparsec , template-haskell+ , mime default-language: Haskell2010