Prevent compromised passwords from being used (#89)

* prevent compromised passwords from being used

* formatting consistency

* run mix format and hardcode api url

* more formatting

* remove unnecessary string upcase
This commit is contained in:
Nick 2020-04-18 20:15:18 -04:00 committed by GitHub
parent ba76ede87d
commit 79d8ed8a1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 1 deletions

View file

@ -0,0 +1,42 @@
defmodule PhilomenaWeb.CompromisedPasswordCheckPlug do
import Phoenix.Controller
def init(opts), do: opts
def call(conn, _opts) do
error_if_password_compromised(conn, conn.params)
end
defp error_if_password_compromised(conn, %{"user" => %{"password" => password}}) do
case password_compromised?(password) do
true ->
conn
|> put_flash(
:error,
"We've detected that the password you entered has been compromised during a data breach of another website. Please choose a different password."
)
|> redirect(external: conn.assigns.referrer)
false ->
conn
end
end
defp error_if_password_compromised(conn, _params),
do: conn
defp password_compromised?(password) do
<<prefix::binary-size(5), rest::binary>> =
:crypto.hash(:sha, password)
|> Base.encode16()
case HTTPoison.get(make_api_url(prefix)) do
{:ok, %HTTPoison.Response{body: body, status_code: 200}} -> String.contains?(body, rest)
_ -> false
end
end
defp make_api_url(prefix) do
"https://api.pwnedpasswords.com/range/#{prefix}"
end
end

View file

@ -52,13 +52,23 @@ defmodule PhilomenaWeb.Router do
plug PhilomenaWeb.FilterBannedUsersPlug plug PhilomenaWeb.FilterBannedUsersPlug
end end
pipeline :ensure_password_not_compromised do
plug PhilomenaWeb.CompromisedPasswordCheckPlug
end
pipeline :protected do pipeline :protected do
plug Pow.Plug.RequireAuthenticated, plug Pow.Plug.RequireAuthenticated,
error_handler: Pow.Phoenix.PlugErrorHandler error_handler: Pow.Phoenix.PlugErrorHandler
end end
scope "/" do scope "/" do
pipe_through [:browser, :ensure_totp, :ensure_not_banned, :ensure_tor_authorized] pipe_through [
:browser,
:ensure_totp,
:ensure_not_banned,
:ensure_tor_authorized,
:ensure_password_not_compromised
]
pow_registration_routes() pow_registration_routes()
end end