Log a warning when a CSRF error occurs

* Closes #1192
This commit is contained in:
Maximilian Tagher 2016-03-28 12:21:50 -07:00
parent 063cef70ee
commit 28fbaae268

View File

@ -252,6 +252,7 @@ import qualified Yesod.Core.TypeCache as Cache
import qualified Data.Word8 as W8 import qualified Data.Word8 as W8
import qualified Data.Foldable as Fold import qualified Data.Foldable as Fold
import Data.Default import Data.Default
import Control.Monad.Logger (MonadLogger, logWarnS)
get :: MonadHandler m => m GHState get :: MonadHandler m => m GHState
get = liftHandlerT $ HandlerT $ I.readIORef . handlerState get = liftHandlerT $ HandlerT $ I.readIORef . handlerState
@ -1439,14 +1440,16 @@ hasValidCsrfParamNamed paramName = do
-- If the value doesn't match the token stored in the session, this function throws a 'PermissionDenied' error. -- If the value doesn't match the token stored in the session, this function throws a 'PermissionDenied' error.
-- --
-- Since 1.4.14 -- Since 1.4.14
checkCsrfHeaderOrParam :: MonadHandler m checkCsrfHeaderOrParam :: (MonadHandler m, MonadLogger m)
=> CI S8.ByteString -- ^ The header name to lookup the CSRF token => CI S8.ByteString -- ^ The header name to lookup the CSRF token
-> Text -- ^ The POST parameter name to lookup the CSRF token -> Text -- ^ The POST parameter name to lookup the CSRF token
-> m () -> m ()
checkCsrfHeaderOrParam headerName paramName = do checkCsrfHeaderOrParam headerName paramName = do
validHeader <- hasValidCsrfHeaderNamed headerName validHeader <- hasValidCsrfHeaderNamed headerName
validParam <- hasValidCsrfParamNamed paramName validParam <- hasValidCsrfParamNamed paramName
unless (validHeader || validParam) (permissionDenied csrfErrorMessage) unless (validHeader || validParam) $ do
$logWarnS "yesod-core" csrfErrorMessage
permissionDenied csrfErrorMessage
validCsrf :: Maybe Text -> Maybe S.ByteString -> Bool validCsrf :: Maybe Text -> Maybe S.ByteString -> Bool
-- It's important to use constant-time comparison (constEqBytes) in order to avoid timing attacks. -- It's important to use constant-time comparison (constEqBytes) in order to avoid timing attacks.