packages feed

happstack-server 7.7.1.2 → 7.7.2

raw patch · 2 files changed

+26/−3 lines, 2 filesdep ~textPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: text

API changes (from Hackage documentation)

Files

happstack-server.cabal view
@@ -1,5 +1,5 @@ Name:                happstack-server-Version:             7.7.1.2+Version:             7.7.2 Synopsis:            Web related tools and services. Description:         Happstack Server provides an HTTP server and a rich set of functions for routing requests, handling query parameters, generating responses, working with cookies, serving files, and more. For in-depth documentation see the Happstack Crash Course <http://happstack.com/docs/crashcourse/index.html> License:             BSD3@@ -86,7 +86,7 @@                        sendfile               >= 0.7.1 && < 0.8,                        system-filepath        >= 0.3.1,                        syb,-                       text                   >= 0.10  && < 1.3,+                       text                   >= 0.10  && < 2.1,                        time,                        threads                >= 0.5,                        transformers           >= 0.1.3 && < 0.7,
src/Happstack/Server/Auth.hs view
@@ -2,8 +2,12 @@ -- | Support for basic access authentication <http://en.wikipedia.org/wiki/Basic_access_authentication> module Happstack.Server.Auth where +import Data.Foldable (foldl')+import Data.Bits (xor, (.|.))+import Data.Maybe (fromMaybe) import Control.Monad                             (MonadPlus(mzero, mplus)) import Data.ByteString.Base64                    as Base64+import qualified Data.ByteString                 as BS import qualified Data.ByteString.Char8           as B import qualified Data.Map                        as M import Happstack.Server.Monads                   (Happstack, escape, getHeaderM, setHeaderM)@@ -72,9 +76,28 @@  -- | Function that looks up the plain text password for username in a -- Map and returns True if it matches with the given password.+--+-- Note: The implementation is hardened against timing attacks but not+-- completely safe. Ideally you should build your own predicate, using+-- a robust constant-time equality comparison from a cryptographic+-- library like sodium. validLoginPlaintext ::   M.Map String String -- ^ the username password map   -> B.ByteString -- ^ the username   -> B.ByteString -- ^ the password   -> Bool-validLoginPlaintext authMap name password = M.lookup (B.unpack name) authMap == Just (B.unpack password)+validLoginPlaintext authMap name password = fromMaybe False $ do+    r <- M.lookup (B.unpack name) authMap+    pure (constTimeEq (B.pack r) password)+  where+    -- (Mostly) constant time equality of bytestrings to prevent timing attacks by testing out passwords. This still+    -- allows to extract the length of the configured password via timing attacks. This implementation is still brittle+    -- in the sense that it relies on GHC not unrolling or vectorizing the loop.+    {-# NOINLINE constTimeEq #-}+    constTimeEq :: BS.ByteString -> BS.ByteString -> Bool+    constTimeEq x y+      | BS.length x /= BS.length y+      = False++      | otherwise+      = foldl' (.|.) 0 (BS.zipWith xor x y) == 0