packages feed

yesod-csp 0.2.7.1 → 0.2.8.0

raw patch · 5 files changed

+52/−7 lines, 5 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- 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: instance Data.Data.Data Yesod.Csp.Directive
- Yesod.Csp: instance Data.Data.Data Yesod.Csp.EscapedText
- Yesod.Csp: instance Data.Data.Data Yesod.Csp.EscapedURI
- Yesod.Csp: instance Data.Data.Data Yesod.Csp.SandboxOptions
- Yesod.Csp: instance Data.Data.Data Yesod.Csp.Source
- Yesod.Csp: instance GHC.Show.Show Yesod.Csp.Directive
- Yesod.Csp: instance GHC.Show.Show Yesod.Csp.EscapedText
- Yesod.Csp: instance GHC.Show.Show Yesod.Csp.EscapedURI
- Yesod.Csp: instance GHC.Show.Show Yesod.Csp.SandboxOptions
- Yesod.Csp: instance GHC.Show.Show Yesod.Csp.Source
- Yesod.Csp.Example: instance GHC.Read.Read (Yesod.Routes.Class.Route Yesod.Csp.Example.Example)
- Yesod.Csp.Example: instance GHC.Show.Show (Yesod.Routes.Class.Route Yesod.Csp.Example.Example)
+ Yesod.Csp: ManifestSrc :: SourceList -> Directive
+ Yesod.Csp: PrefetchSrc :: SourceList -> Directive
+ Yesod.Csp: ReportTo :: Text -> Directive
+ Yesod.Csp: WorkerSrc :: SourceList -> Directive
+ Yesod.Csp: instance GHC.Internal.Data.Data.Data Codec.MIME.Type.MIMEParam
+ Yesod.Csp: instance GHC.Internal.Data.Data.Data Codec.MIME.Type.MIMEType
+ Yesod.Csp: instance GHC.Internal.Data.Data.Data Codec.MIME.Type.Multipart
+ Yesod.Csp: instance GHC.Internal.Data.Data.Data Codec.MIME.Type.Type
+ Yesod.Csp: instance GHC.Internal.Data.Data.Data Yesod.Csp.Directive
+ Yesod.Csp: instance GHC.Internal.Data.Data.Data Yesod.Csp.EscapedText
+ Yesod.Csp: instance GHC.Internal.Data.Data.Data Yesod.Csp.EscapedURI
+ Yesod.Csp: instance GHC.Internal.Data.Data.Data Yesod.Csp.SandboxOptions
+ Yesod.Csp: instance GHC.Internal.Data.Data.Data Yesod.Csp.Source
+ Yesod.Csp: instance GHC.Internal.Show.Show Yesod.Csp.Directive
+ Yesod.Csp: instance GHC.Internal.Show.Show Yesod.Csp.EscapedText
+ Yesod.Csp: instance GHC.Internal.Show.Show Yesod.Csp.EscapedURI
+ Yesod.Csp: instance GHC.Internal.Show.Show Yesod.Csp.SandboxOptions
+ Yesod.Csp: instance GHC.Internal.Show.Show Yesod.Csp.Source
+ Yesod.Csp.Example: instance GHC.Internal.Read.Read (Yesod.Routes.Class.Route Yesod.Csp.Example.Example)
+ Yesod.Csp.Example: instance GHC.Internal.Show.Show (Yesod.Routes.Class.Route Yesod.Csp.Example.Example)
+ Yesod.Csp.TH: reportTo :: Parser Directive

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # Changelog +## Version 0.2.8.0+++ Add support for CSP Level 3 directives: `report-to`, `worker-src`, `manifest-src` and `prefetch-src`+ ## Version 0.2.7.1  + Relax version boundaries on template-haskell to be able to build with ghc-9.10 on nixos-25.11
src/Yesod/Csp.hs view
@@ -171,6 +171,12 @@                  | FormAction SourceList                  | BaseUri EscapedURI                  | PluginTypes MimeTypeList+                 -- | CSP level 3 directives+                 | WorkerSrc SourceList+                 | ManifestSrc SourceList+                 | PrefetchSrc SourceList+                 -- | Names a reporting group defined by the @Reporting-Endpoints@ (or @Report-To@) response header.+                 | ReportTo Text                  deriving (Eq, Show, Data, Typeable)  @@ -202,3 +208,7 @@ 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]+textDirective (WorkerSrc x) = w "worker-src" x+textDirective (ManifestSrc x) = w "manifest-src" x+textDirective (PrefetchSrc x) = w "prefetch-src" x+textDirective (ReportTo t) = mconcat ["report-to ", t]
src/Yesod/Csp/TH.hs view
@@ -4,6 +4,7 @@     source     , withSourceList     , reportUri+    , reportTo     , pluginTypes     , sandbox     , sandboxOptions@@ -110,6 +111,9 @@                  <|> frameAncestors                  <|> childSrc                  <|> formAction+                 <|> workerSrc+                 <|> manifestSrc+                 <|> prefetchSrc   where defaultSrc = d "default-src" DefaultSrc         scriptSrc = d "script-src" ScriptSrc         styleSrc = d "style-src" StyleSrc@@ -122,6 +126,9 @@         frameAncestors = d "frame-ancestors" FrameAncestors         childSrc = d "child-src" ChildSrc         formAction = d "form-action" FormAction+        workerSrc = d "worker-src" WorkerSrc+        manifestSrc = d "manifest-src" ManifestSrc+        prefetchSrc = d "prefetch-src" PrefetchSrc         d x y = string x >> s >> slist >>= mkWithSource y         slist = sepBy1 source (char ' ')         s = spaces@@ -138,6 +145,15 @@     Nothing -> fail "reportUri" -- n.b. compile time error     Just uri -> return $ ReportUri uri +reportTo :: Parser Directive+reportTo = do+  _ <- string "report-to"+  _ <- spaces+  g <- takeTill separated+  if T.null g+    then fail "reportTo" -- n.b. compile time error+    else return $ ReportTo g+ baseUri :: Parser Directive baseUri = do   _ <- string "base-uri"@@ -179,4 +195,4 @@  directive :: Parser DirectiveList directive = sepBy (spaces *> d) separator <* (spaces *> endOfInput)-  where d = withSourceList <|> reportUri <|> baseUri <|> pluginTypes <|> sandbox+  where d = withSourceList <|> reportUri <|> reportTo <|> baseUri <|> pluginTypes <|> sandbox
test/Test.hs view
@@ -6,7 +6,6 @@  import           Codec.MIME.Parse          (parseMIMEType) import           Data.Attoparsec.Text-import           Data.Functor         ((<$>)) import           Data.List.NonEmpty import           Data.Maybe import           Test.Hspec@@ -62,6 +61,18 @@       let dom = pure $ fromJust $ parseMIMEType "text/plain"           header = getCspPolicy [PluginTypes dom]       assertEq "plugin-types" header "plugin-types text/plain"+    yit "works with worker-src" $ do+      let header = getCspPolicy [WorkerSrc (Self :| [])]+      assertEq "worker-src" header "worker-src 'self'"+    yit "works with manifest-src" $ do+      let header = getCspPolicy [ManifestSrc (Self :| [])]+      assertEq "manifest-src" header "manifest-src 'self'"+    yit "works with prefetch-src" $ do+      let header = getCspPolicy [PrefetchSrc (Https :| [Self])]+      assertEq "prefetch-src" header "prefetch-src https: 'self'"+    yit "works with report-to" $ do+      let header = getCspPolicy [ReportTo "csp-endpoint"]+      assertEq "report-to" header "report-to csp-endpoint"   ydescribe "Headers" $     yit "get set" $ do       get HomeR@@ -86,12 +97,16 @@       assertEq "unsafe-eval" (parseOnly source "unsafe-eval") (Right UnsafeEval)       assertEq "default-src self data:" (parseOnly withSourceList "default-src 'self' data:") (Right $ DefaultSrc (Self :| [DataScheme]))       assertEq "report-uri http://hello.com" (parseOnly reportUri "report-uri http://hello.com") (Right $ ReportUri (fromJust (escapeAndParseURI "http://hello.com")))+      assertEq "report-to csp-endpoint" (parseOnly reportTo "report-to csp-endpoint") (Right $ ReportTo "csp-endpoint")+      assertEq "worker-src self" (parseOnly withSourceList "worker-src 'self'") (Right $ WorkerSrc (Self :| []))+      assertEq "manifest-src self" (parseOnly withSourceList "manifest-src 'self'") (Right $ ManifestSrc (Self :| []))+      assertEq "prefetch-src self" (parseOnly withSourceList "prefetch-src 'self'") (Right $ PrefetchSrc (Self :| []))       assertEq "sandbox allow-forms allow-scripts" (parseOnly sandbox "sandbox allow-forms allow-scripts") (Right $ Sandbox [AllowForms, AllowScripts])     yit "works with lists" $ do-      let result = [ImgSrc $ Self :| [Https], ScriptSrc $ Host (fromJust $ escapeAndParseURI "https://foo.com") :| []]-      assertEq "scripts and images" (parseOnly directive "img-src 'self' https:; script-src https://foo.com") (Right result)-      let result = [ImgSrc $ Self :| [DataScheme, Host (fromJust $ escapeAndParseURI "https://foo.com")]]-      assertEq "data and hosts" (parseOnly directive "img-src 'self' data: https://foo.com") (Right result)+      let resultHttps = [ImgSrc $ Self :| [Https], ScriptSrc $ Host (fromJust $ escapeAndParseURI "https://foo.com") :| []]+      assertEq "scripts and images" (parseOnly directive "img-src 'self' https:; script-src https://foo.com") (Right resultHttps)+      let resultData = [ImgSrc $ Self :| [DataScheme, Host (fromJust $ escapeAndParseURI "https://foo.com")]]+      assertEq "data and hosts" (parseOnly directive "img-src 'self' data: https://foo.com") (Right resultData)     yit "works with nonces and th" $ do       let result = [ScriptSrc $ (nonce "foo") :| []]       assertEq "nonces and th" [csp|script-src 'nonce-foo'|] result
yesod-csp.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                yesod-csp-version:             0.2.7.1+version:             0.2.8.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