| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Wai.CSRF
Contents
Description
This module exports tool to prevent cross-site request forgeries in Network.Wai. Consider using it in combination with Wai.CryptoCookie.
Synopsis
- data Config = Config {
- cookieName :: ByteString
- headerName :: ByteString
- reject :: Request -> Maybe (Token, Bool) -> Maybe Response
- defaultConfig :: Config
- tokenFromRequestHeader :: Config -> Request -> Maybe Token
- tokenFromRequestCookie :: Config -> Request -> Maybe Token
- setCookie :: Config -> Token -> SetCookie
- expireCookie :: Config -> SetCookie
- middleware :: Config -> (Maybe Token -> Application) -> Application
- newtype Token = Token (SizedByteArray 32 ByteString)
- randomToken :: MonadRandom m => m Token
- tokenToBase64UU :: Token -> ByteString
- tokenFromBase64UU :: ByteString -> Maybe Token
- newtype MaskedToken = MaskedToken (SizedByteArray 64 Bytes)
- maskedTokenToBase64UU :: MaskedToken -> ByteString
- maskedTokenFromBase64UU :: ByteString -> Maybe MaskedToken
- randomMaskToken :: MonadRandom m => Token -> m MaskedToken
- unmaskToken :: MaskedToken -> Token
Documentation
Config common to middleware, tokenFromRequestHeader and
tokenFromRequestCookie.
Consider using defaultConfig and updating desired fields only.
Constructors
| Config | |
Fields
| |
defaultConfig :: Config Source #
Default CSRF settings.
- Cookie name is
CSRF-TOKEN. - Header name is
X-CSRF-TOKEN. - Reject with
forbidden403all request who are neitherGET,HEAD,OPTIONSnorTRACE, unless theTokenis present in both cookie and header and they are equal.
tokenFromRequestHeader :: Config -> Request -> Maybe Token Source #
Obtain the Token from the Request headers.
You don't need to use this if you are using middleware.
tokenFromRequestCookie :: Config -> Request -> Maybe Token Source #
Obtain the Token from the Request cookies.
You don't need to use this if you are using middleware.
setCookie :: Config -> Token -> SetCookie Source #
Construct a SetCookie to set the CSRF Token.
The SetCookie has these settings, some of which could be overriden.
- Cookie name is
Config'scookieName. HttpOnly: No, and you shouldn't change this.Max-AgeandExpires: This cookie never expires. We recommend relying on server-side expiration instead, as the lifetime of the cookie could easily be extended by a legitimate but malicious client. It is recommended that you rotate theTokeneach time a new user session is established.Path:/SameSite:Lax.Secure: Yes.Domain: Not set.
expireCookie :: Config -> SetCookie Source #
middleware :: Config -> (Maybe Token -> Application) -> Application Source #
Construct a Middleware (almost) that does the following:
- Try to find the CSRF
Tokenamong the incomingRequestcookies (seeConfig'scookieName). - Use
Config'srejectto decide if the incomingRequestshould be rejected. - If the
Requestwasn't rejected, we pass theTokenfound in the cookie, if any, to the underlyingApplication.
Important: This doesn't set any cookie. You must explicitly add
setCookie to a Response yourself.
Token
CSRF token.
- It is safe to send and receive the
Tokenthrough HTTP cookies and headers. - If you need to send or receive the
Tokenas part of the request or response body, useMaskedTokeninstead.
Constructors
| Token (SizedByteArray 32 ByteString) |
randomToken :: MonadRandom m => m Token Source #
A CSRF token is just random 32 bytes. Its meaning and validity depends on how and whether you tie it to a user session.
Masked token
newtype MaskedToken Source #
If you embed a Token as is in a response body when HTTP body compression
is enabled, it is possible for a malicious actor to recover the Token
through a BREACH attack or similar. In order to prevent that, send a
different MaskedToken (generated with randomMaskToken) each time
instead.
Constructors
| MaskedToken (SizedByteArray 64 Bytes) |
Instances
| Show MaskedToken Source # | |
Defined in Wai.CSRF Methods showsPrec :: Int -> MaskedToken -> ShowS # show :: MaskedToken -> String # showList :: [MaskedToken] -> ShowS # | |
| Eq MaskedToken Source # | |
Defined in Wai.CSRF | |
randomMaskToken :: MonadRandom m => Token -> m MaskedToken Source #
and unmaskToken <$> randomMaskToken tok produce
the same output pure toktok.
unmaskToken :: MaskedToken -> Token Source #
and unmaskToken <$> randomMaskToken tok produce
the same output pure toktok.