Merge pull request #1200 from MaxGabriel/logCSRFErrors

Log a warning when a CSRF error occurs
This commit is contained in:
Maximilian Tagher 2016-03-29 10:14:41 -07:00
commit 09087c934e
3 changed files with 11 additions and 4 deletions

View File

@ -1,3 +1,7 @@
## 1.4.20.1
* Log a warning when a CSRF error occurs [#1200](https://github.com/yesodweb/yesod/pull/1200)
## 1.4.20 ## 1.4.20
* `addMessage`, `addMessageI`, and `getMessages` functions * `addMessage`, `addMessageI`, and `getMessages` functions

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.
@ -1455,4 +1458,4 @@ validCsrf Nothing _param = True
validCsrf (Just _token) Nothing = False validCsrf (Just _token) Nothing = False
csrfErrorMessage :: Text csrfErrorMessage :: Text
csrfErrorMessage = "A valid CSRF token wasn't present in HTTP headers or POST parameters. Check the Yesod.Core.Handler docs of the yesod-core package for details on CSRF protection." csrfErrorMessage = "A valid CSRF token wasn't present in HTTP headers or POST parameters. Because the request could have been forged, it's been rejected altogether. Check the Yesod.Core.Handler docs of the yesod-core package for details on CSRF protection."

View File

@ -1,5 +1,5 @@
name: yesod-core name: yesod-core
version: 1.4.20 version: 1.4.20.1
license: MIT license: MIT
license-file: LICENSE license-file: LICENSE
author: Michael Snoyman <michael@snoyman.com> author: Michael Snoyman <michael@snoyman.com>