haveibeenpwned

Library for checking for weak/compromised passwords.

Stackage Nightly 2025-05-08:0.2.0.3
Latest on Hackage:0.2.0.3

See all snapshots haveibeenpwned appears in

BSD-3-Clause licensed by Obsidian Systems LLC
Maintained by [email protected]
This version can be pinned in stack with:haveibeenpwned-0.2.0.3@sha256:db61209c70bf4607166192c0bf2373554cbc1fa3b42696180acaf0e4f37cfe4c,1594

Module documentation for 0.2.0.3

haveibeenpwned

Haskell Hackage Hackage CI Github CI travis-ci BSD3 License

A haskell library for checking passwords against the haveibeenpwned.com database.

By means of this library you can do some basic strength check on new user passwords. Common weak passwords like many plain English words or also many stronger passwords which happen to have been leaked will likely be found in the database and can thus be rejected.

Example

The example below can be built and run using cabal build exe:readme or cabal repl exe:readme.


> {-# LANGUAGE OverloadedStrings #-}
>
> import Control.Monad.IO.Class (liftIO)
> import Control.Monad.Logger (runStdoutLoggingT)
> import Control.Exception (bracket_)
> import Data.Text as T (pack)
> import Network.HTTP.Client (newManager)
> import Network.HTTP.Client.TLS (tlsManagerSettings)
> import System.IO (hFlush, stdout, hGetEcho, stdin, hSetEcho)
>
> import HaveIBeenPwned
>
> -- | A really simple demo of the hibp functionality. Asks the user to enter
> -- a password and then uses the hibp api to check whether that password has
> -- been pwned.
> consoleHaveIBeenPwned :: IO ()
> consoleHaveIBeenPwned = do
>   runStdoutLoggingT $ do
>     mgr <- liftIO $ newManager tlsManagerSettings
>     p <- liftIO $ getPassword
>     let hibpEnv = HaveIBeenPwnedConfig mgr "https://api.pwnedpasswords.com/range"
>     p' <- flip runPwnedT hibpEnv $ haveIBeenPwned $ T.pack p
>     liftIO $ case p' of
>       HaveIBeenPwnedResult_Secure ->
>         putStrLn "Your password does not appear in any known breaches.  Practice good password hygene."
>       HaveIBeenPwnedResult_Pwned p'' ->
>         putStrLn $ "You have been pwned! Your password has appeared in breaches " ++ show p'' ++ " times."
>       HaveIBeenPwnedResult_Error ->
>         putStrLn "Network Error, try again later"
>
> getPassword :: IO String
> getPassword = do
>   putStr "Password: "
>   hFlush stdout
>   password <- withEcho False getLine
>   putChar '\n'
>   return password
>
> withEcho :: Bool -> IO a -> IO a
> withEcho echo action = do
>   old <- hGetEcho stdin
>   bracket_ (hSetEcho stdin echo) (hSetEcho stdin old) action
>
> main :: IO ()
> main = consoleHaveIBeenPwned


Obsidian Systems

Changes

Revision history for haveibeenpwned

0.2.0.3

  • Support for GHC 9.12

0.2.0.2

  • Support for GHC 9.10

0.2.0.1

  • Add readme to extra-source-files so that it appears on hackage

0.2.0.0

  • Breaking change in order to make the API and the implementation more secure.
    • There is a new HaveIBeenPwnedResult_Secure constructor which signals that the given password was not found in any database.
    • The HaveIBeenPwnedResult_Disclosed constructor has been renamed to HaveIBeenPwnedResult_Pwned, as its behaviour changed. (Valid passwords are no longer signalled by this constructor.)
  • Also internally, a “not found in database” is no longer represented as a disclosed count of zero. This improves security in the case of an incorrect database entry, having a disclosed count of 0, which would make this library report that password as “secure”, although it actually has been leaked.

0.1.0.0

  • Initial release