You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _guides/2019-09-14-password-breach-lookup-and-other-password-validation-rules.md
+21-11Lines changed: 21 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -18,7 +18,7 @@ They are based on the [NIST SP800-63b recommendations](https://pages.nist.gov/80
18
18
19
19
## Passwords obtained from previous breaches
20
20
21
-
To check for breached passwords, we'll use the [haveibeenpwned.com](https://haveibeenpwned.com/).
21
+
We'll use [haveibeenpwned.com](https://haveibeenpwned.com/) to check for breached passwords.
22
22
23
23
For the sake of brevity, we'll use [`ExPwned`](https://hex.pm/packages/ex_pwned) in the following example, but you can use any client or your own [custom module](https://ieftimov.com/post/haveibeenpwned-password-lookup-elixir/) to communicate with the API.
24
24
@@ -35,7 +35,7 @@ end
35
35
36
36
Run `mix deps.get` to install it.
37
37
38
-
Now let's add the password validation rule to the user module:
38
+
Now let's add the password validation rule to our user schema module:
39
39
40
40
```elixir
41
41
defmoduleMyApp.Users.Userdo
@@ -72,7 +72,13 @@ We'll only do a lookup if the password has been changed, and we don't do any loo
72
72
73
73
## Context-specific words, such as the name of the service, the username, and derivatives thereof
74
74
75
-
We want to prevent context specific words. If the user id is `[email protected]` (or `john.doe` if username), then the password can't be `[email protected]` or `johndoeexamplecom` (or for username `john.doe00` or `johndoe001`). Likewise, our platform may be called `My Demo App` so we don't want to permit a passwords like `my demo app`, `my_demo_app` or `mydemoapp`.
75
+
We want to prevent context specific words to be used as passwords.
76
+
77
+
The context might be public user details. If the users email is `[email protected]` then the password can't be `[email protected]` or `johndoeexamplecom`. The same rule applies for any user id we may use, such as username. If the username is `john.doe` then `john.doe00` or `johndoe001` can't be used.
78
+
79
+
Our app may also be part of a website/service/platform and have an identity. As an example, if the service is called `My Demo App` then we don't want to permit passwords like `my demo app`, `my_demo_app` or `mydemoapp`.
80
+
81
+
We'll add the password validation rule to our user schema module:
76
82
77
83
```elixir
78
84
defmoduleMyApp.Users.Userdo
@@ -116,7 +122,9 @@ We're using the [`String.jaro_distance/2`](https://hexdocs.pm/elixir/String.html
116
122
117
123
## Repetitive or sequential characters
118
124
119
-
We want to prevent repetitive passwords such as `aaa`, `1234` or `abcd`. We'll set up the following validations so there may be no more than two repeating or three sequential characters in the password.
125
+
We want to prevent repetitive or sequential characters in passwords such as `aaa`, `1234` or `abcd`.
126
+
127
+
The rule we'll use is that there may be no more than two repeating or three sequential characters in the password. We'll add the validation rule to our user schema module:
120
128
121
129
```elixir
122
130
defmoduleMyApp.Users.Userdo
@@ -183,11 +191,11 @@ defmodule MyApp.Users.User do
183
191
end
184
192
```
185
193
186
-
As you can see, you'll be able to modify `@sequences` and add what is appropriate for your app. It may be that you want to support another alphabet or keyboard sequences like `qwerty`.
194
+
As you can see, you'll be able to modify `@sequences` and add what is appropriate for your app. It may be that you want to support another alphabet or keyboard layout sequences like `qwerty`.
187
195
188
196
## Dictionary words
189
197
190
-
A dictionary lookup is very easy to create, so we will only provide a very simple example:
198
+
A dictionary lookup is very easy to create. This is just a very simple example that you can add to your user schema module:
191
199
192
200
```elixir
193
201
defmoduleMyApp.Users.Userdo
@@ -228,15 +236,13 @@ defmodule MyApp.Users.User do
228
236
end
229
237
```
230
238
231
-
This will iterate through a plain text file with all dictionary words separated by newlines.
239
+
In the above `priv/dictionary.txt`will be processed on compile time. The plain text file contains words separated by newline.
232
240
233
241
## Require users to change weak password upon sign in
234
242
235
243
You may want to ensure that users update their password if they have been breached or are too weak. You can do this be requiring users to reset their password upon sign in.
236
244
237
-
This can be dealt with in a plug, or [custom controller](https://hexdocs.pm/pow/custom_controllers.html).
238
-
239
-
Here's how a plug method could look:
245
+
This can be dealt with in a plug, or [custom controller](https://hexdocs.pm/pow/custom_controllers.html). A plug method could look like this:
240
246
241
247
```elixir
242
248
defcheck_password(conn, _opts) do
@@ -257,11 +263,15 @@ def check_password(conn, _opts) do
257
263
end
258
264
```
259
265
266
+
The user will be redirected to the reset password page, and the connection halted so authentication won't happen. A caveat to this is that the user may not have entered valid credentials, since this runs before any authentication.
267
+
260
268
## Conclusion
261
269
262
270
As you can see it is easy to customize and extend the password validation rules of Pow.
263
271
264
-
The landscape of web security is constantly changing, so it's important that password requirements are neither so restricting that it affects user experience or too lax that it affects security. The above will work for most cases in the current landscape, but you should also consider supporting 2FA authentication, or alternative authentication schemes such as WebAuthn or OAuth. It depends on your requirements and risk tolerance. It's recommended to take your time to assess what is appropriate for your app.
272
+
The landscape of web security is constantly changing, so it's important that password requirements are neither so restricting that it affects user experience or too lax that it affects security. The above will work for most cases in the current landscape, but you should also consider supporting 2FA authentication, or alternative authentication schemes such as WebAuthn or OAuth.
273
+
274
+
It depends on your requirements and risk tolerance. It's recommended to take your time to assess what is appropriate for your app.
0 commit comments