Add laxSameSiteSessions and strictSameSiteSessions
This commit is contained in:
parent
2cbe60c53d
commit
a797c2e5d4
@ -53,6 +53,8 @@ module Yesod.Core
|
|||||||
, envClientSessionBackend
|
, envClientSessionBackend
|
||||||
, clientSessionBackend
|
, clientSessionBackend
|
||||||
, sslOnlySessions
|
, sslOnlySessions
|
||||||
|
, laxSameSiteSessions
|
||||||
|
, strictSameSiteSessions
|
||||||
, sslOnlyMiddleware
|
, sslOnlyMiddleware
|
||||||
, clientSessionDateCacher
|
, clientSessionDateCacher
|
||||||
, loadClientSession
|
, loadClientSession
|
||||||
|
|||||||
@ -49,7 +49,7 @@ import qualified Text.Blaze.Html5 as TBH
|
|||||||
import Text.Hamlet
|
import Text.Hamlet
|
||||||
import Text.Julius
|
import Text.Julius
|
||||||
import qualified Web.ClientSession as CS
|
import qualified Web.ClientSession as CS
|
||||||
import Web.Cookie (parseCookies)
|
import Web.Cookie (parseCookies, sameSiteLax, sameSiteStrict, SameSiteOption)
|
||||||
import Web.Cookie (SetCookie (..))
|
import Web.Cookie (SetCookie (..))
|
||||||
import Yesod.Core.Types
|
import Yesod.Core.Types
|
||||||
import Yesod.Core.Internal.Session
|
import Yesod.Core.Internal.Session
|
||||||
@ -366,6 +366,22 @@ sslOnlySessions = (fmap . fmap) secureSessionCookies
|
|||||||
setSecureBit cookie = cookie { setCookieSecure = True }
|
setSecureBit cookie = cookie { setCookieSecure = True }
|
||||||
secureSessionCookies = customizeSessionCookies setSecureBit
|
secureSessionCookies = customizeSessionCookies setSecureBit
|
||||||
|
|
||||||
|
-- | Helps defend against CSRF attacks by setting the SameSite attribute on
|
||||||
|
-- session cookies to "Lax".
|
||||||
|
laxSameSiteSessions :: IO (Maybe SessionBackend) -> IO (Maybe SessionBackend)
|
||||||
|
laxSameSiteSessions = sameSiteSession sameSiteLax
|
||||||
|
|
||||||
|
-- | Helps defend against CSRF attacks by setting the SameSite attribute on
|
||||||
|
-- session cookies to "Strict".
|
||||||
|
strictSameSiteSessions :: IO (Maybe SessionBackend) -> IO (Maybe SessionBackend)
|
||||||
|
strictSameSiteSessions = sameSiteSession sameSiteStrict
|
||||||
|
|
||||||
|
sameSiteSession :: SameSiteOption -> IO (Maybe SessionBackend) -> IO (Maybe SessionBackend)
|
||||||
|
sameSiteSession s = (fmap . fmap) secureSessionCookies
|
||||||
|
where
|
||||||
|
sameSite cookie = cookie { setCookieSameSite = (pure s) }
|
||||||
|
secureSessionCookies = customizeSessionCookies sameSite
|
||||||
|
|
||||||
-- | Apply a Strict-Transport-Security header with the specified timeout to
|
-- | Apply a Strict-Transport-Security header with the specified timeout to
|
||||||
-- all responses so that browsers will rewrite all http links to https
|
-- all responses so that browsers will rewrite all http links to https
|
||||||
-- until the timeout expires. For security, the max-age of the STS header
|
-- until the timeout expires. For security, the max-age of the STS header
|
||||||
|
|||||||
@ -48,4 +48,5 @@ specs = do
|
|||||||
LiteApp.specs
|
LiteApp.specs
|
||||||
Ssl.unsecSpec
|
Ssl.unsecSpec
|
||||||
Ssl.sslOnlySpec
|
Ssl.sslOnlySpec
|
||||||
|
Ssl.sameSiteSpec
|
||||||
Csrf.csrfSpec
|
Csrf.csrfSpec
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
|
{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
|
||||||
module YesodCoreTest.Ssl ( sslOnlySpec, unsecSpec ) where
|
module YesodCoreTest.Ssl ( sslOnlySpec, unsecSpec, sameSiteSpec ) where
|
||||||
import qualified YesodCoreTest.StubSslOnly as Ssl
|
import qualified YesodCoreTest.StubSslOnly as Ssl
|
||||||
|
import qualified YesodCoreTest.StubLaxSameSite as LaxSameSite
|
||||||
|
import qualified YesodCoreTest.StubStrictSameSite as StrictSameSite
|
||||||
import qualified YesodCoreTest.StubUnsecured as Unsecured
|
import qualified YesodCoreTest.StubUnsecured as Unsecured
|
||||||
import Yesod.Core
|
import Yesod.Core
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
@ -62,3 +64,15 @@ unsecSpec = describe "A Yesod application with sslOnly off" $ do
|
|||||||
where
|
where
|
||||||
atHome = homeFixtureFor Unsecured.App
|
atHome = homeFixtureFor Unsecured.App
|
||||||
isNotSecure c = not $ Cookie.setCookieSecure c
|
isNotSecure c = not $ Cookie.setCookieSecure c
|
||||||
|
|
||||||
|
sameSiteSpec :: Spec
|
||||||
|
sameSiteSpec = describe "A Yesod application" $ do
|
||||||
|
it "can set a Lax SameSite option" $
|
||||||
|
laxHome $ "_SESSION" `cookieShouldSatisfy` isLax
|
||||||
|
it "can set a Strict SameSite option" $
|
||||||
|
strictHome $ "_SESSION" `cookieShouldSatisfy` isStrict
|
||||||
|
where
|
||||||
|
laxHome = homeFixtureFor LaxSameSite.App
|
||||||
|
strictHome = homeFixtureFor StrictSameSite.App
|
||||||
|
isLax = (== Just Cookie.sameSiteLax) . Cookie.setCookieSameSite
|
||||||
|
isStrict = (== Just Cookie.sameSiteStrict) . Cookie.setCookieSameSite
|
||||||
|
|||||||
23
yesod-core/test/YesodCoreTest/StubLaxSameSite.hs
Normal file
23
yesod-core/test/YesodCoreTest/StubLaxSameSite.hs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
|
||||||
|
module YesodCoreTest.StubLaxSameSite ( App ( App ) ) where
|
||||||
|
|
||||||
|
import Yesod.Core
|
||||||
|
import qualified Web.ClientSession as CS
|
||||||
|
|
||||||
|
data App = App
|
||||||
|
|
||||||
|
mkYesod "App" [parseRoutes|
|
||||||
|
/ HomeR GET
|
||||||
|
|]
|
||||||
|
|
||||||
|
instance Yesod App where
|
||||||
|
yesodMiddleware = defaultYesodMiddleware . (sslOnlyMiddleware 120)
|
||||||
|
makeSessionBackend _ = laxSameSiteSessions $
|
||||||
|
fmap Just $ defaultClientSessionBackend 120 CS.defaultKeyFile
|
||||||
|
|
||||||
|
getHomeR :: Handler Html
|
||||||
|
getHomeR = defaultLayout
|
||||||
|
[whamlet|
|
||||||
|
<p>
|
||||||
|
Welcome to my test application.
|
||||||
|
|]
|
||||||
23
yesod-core/test/YesodCoreTest/StubStrictSameSite.hs
Normal file
23
yesod-core/test/YesodCoreTest/StubStrictSameSite.hs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-}
|
||||||
|
module YesodCoreTest.StubStrictSameSite ( App ( App ) ) where
|
||||||
|
|
||||||
|
import Yesod.Core
|
||||||
|
import qualified Web.ClientSession as CS
|
||||||
|
|
||||||
|
data App = App
|
||||||
|
|
||||||
|
mkYesod "App" [parseRoutes|
|
||||||
|
/ HomeR GET
|
||||||
|
|]
|
||||||
|
|
||||||
|
instance Yesod App where
|
||||||
|
yesodMiddleware = defaultYesodMiddleware . (sslOnlyMiddleware 120)
|
||||||
|
makeSessionBackend _ = strictSameSiteSessions $
|
||||||
|
fmap Just $ defaultClientSessionBackend 120 CS.defaultKeyFile
|
||||||
|
|
||||||
|
getHomeR :: Handler Html
|
||||||
|
getHomeR = defaultLayout
|
||||||
|
[whamlet|
|
||||||
|
<p>
|
||||||
|
Welcome to my test application.
|
||||||
|
|]
|
||||||
Loading…
Reference in New Issue
Block a user