• Stars
    star
    371
  • Rank 115,103 (Top 3 %)
  • Language
    PHP
  • License
    MIT License
  • Created almost 7 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Super simple Laravel Validator for checking password via the Pwned Passwords service of Have I Been Pwned

Pwned Passwords Validator for Laravel

Laravel includes an official Pwned Passwords validator via the Password::uncompromised() validation rule, so I recommend checking that out instead: https://laravel.com/docs/10.x/validation#validating-passwords

The Pwned Password validator checks the user's submitted password (in a registration or password change form) with the awesome HIBP Pwned Passwords service to see if it is a known pwned password. If the password has been pwned, it will fail validation, preventing the user from using that password in your app.

Pwned Passwords are half a billion real world passwords previously exposed in data breaches. This exposure makes them unsuitable for ongoing use as they're at much greater risk of being used to take over other accounts.

This uses the ranged search feature of the Pwned Passwords API, which uses k-anonymity to significantly reduce the risk of any information leakage when accessing the API. For most systems this should be more than secure enough, although you should definitely decide for yourself if it's suitable for your app.

Please make sure to check out the blog post by Troy Hunt, where he explains how the service works: https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/.

Troy worked with Cloudflare on this service, and they have an in depth technical analysis on how it works and the security implications: https://blog.cloudflare.com/validating-leaked-passwords-with-k-anonymity/.

Ultimately, it's up to you to decide if it's safe for your app or not.

Installation

Install the package using Composer:

composer require valorin/pwned-validator

Laravel's service provider discovery will automatically configure the Pwned service provider for you.

Add the validation message to your validation lang file:

For each language add a validation message to validation.php like below

'pwned' => 'The :attribute is not secure enough',

Using the pwned validator

After installation, the pwned validator will be available for use directly in your validation rules.

'password' => 'pwned',

Within the context of a registration form, it would look like this:

return Validator::make($data, [
    'name' => 'required|string|max:255',
    'email' => 'required|string|email|max:255|unique:users',
    'password' => 'required|string|min:6|pwned|confirmed',
]);

Using the Rule Object

Alternatively, you can use the Valorin\Pwned\Pwned Validation Rule Object instead of the pwned alias if you prefer:

return Validator::make($data, [
    'name' => 'required|string|max:255',
    'email' => 'required|string|email|max:255|unique:users',
    'password' => ['required', 'string', 'min:6', new \Valorin\Pwned\Pwned, 'confirmed'],
]);

Validation message

You will need to assign your own validation message within the resources/lang/*/validation.php file(s). Both the Rule object and the pwned validator alias refer to the validation string validation.pwned.

I haven't set a default language string as it is important you get the language right for your intended users. In some systems a message like Your password has been pwned! Please use a new one! is suitable, while in other systems you'd be better with something a lot longer:

Your password is insufficiently secure as it has been found in known password breaches, please choose a new one. Need help?

Thanks to kanalumaddela, you can use :min in the message to indicate the minimum number of times found set on the validator.

Your password is insufficiently secure as it has been found at least :min times in known password breaches, please choose a new one.

Limiting by the number of times the password was pwned

You can also limit rejected passwords to those that have been pwned a minimum number of times. For example, password has been pwned 3,303,003 times, however P@ssword! has only been pwned 118 times. If we wanted to block password but not P@ssword!, we can specify the minimum number as 150 like this:

'password' => 'required|string|min:6|pwned:150|confirmed',

or using the Rule object:

'password' => ['required', 'string', 'min:6', new \Valorin\Pwned\Pwned(150), 'confirmed'],

FAQs

Q: How secure is this?
A: Please check the above linked blog posts by Troy Hunt and Cloudflare, as they will answer your question and help you decide if it's safe enough for you.

Q: Do you do any caching?
A: Yep! Each prefix query is cached for a week, to prevent constant API requests if the same prefix is checked multiple times.

Q: Where are the tests?
A: To properly test this code, we need to hit the web service. I don't want to automate that, to avoid abusing this fantastic service. Instead, since it is an incredibly simplistic validator, I've opted to manually test it for now.

More Repositories

1

zf2-phinx-module

Integrates the Phinx database migration tool into a ZF2 application.
PHP
21
star
2

pinpusher

Simple Pebble Timeline Pin API wrapper for PHP, with full support for all of the Pebble Timeline API options.
PHP
9
star
3

deploy

Deploy is an Artisan command with the aim to provide a very simple way to deploy your code into staging and production while ensuring valid version tags are applied.
PHP
8
star
4

spirit

PHP security scanner
PHP
8
star
5

samesite

SameSite Cookies Tester - a simple web app to test SameSite cookie behaviours in the browser
PHP
5
star
6

l4-down-safe

Artisan command for switching a Laravel 4 queue worker into maintenance mode alongside the application safely.
PHP
5
star
7

debver

Simple PHP helper class for comparing Debian/Ubuntu package version strings.
PHP
3
star
8

timeparser

Simple PHP class for parsing time values entered by users in a wide range of formats.
PHP
2
star
9

valversion

ZF2 Version Module: Provides an easy database versioning system.
PHP
2
star
10

artisan-serve

Simple Laravel 5 replacement command for `php artisan serve`.
PHP
2
star
11

asyncphp

Asynchronous PHP - Control and manipulate client-side Javascript from server-side PHP.
PHP
1
star
12

random

Random is a simple helper package designed to make it easy to generate a range of different cryptographically secure random values.
PHP
1
star
13

try_git

1
star
14

ValCommon

ZF2 Common Tools Module
PHP
1
star
15

zf2-twitter-bootstrap-module

ZF2 Module for easily including, and modifying, the helpful Twitter Bootstrap framework.
1
star
16

wyoa

Write your own Adventure
PHP
1
star
17

security-headers

Easily deploy security headers in your Laravel app
1
star
18

console

Simple PHP Console interface helper.
PHP
1
star
19

phpnz15-shoutbox

Shoutbox example app for "Ansible, live on stage" at PHPNZ15
PHP
1
star
20

cronsync

CronSync is a way to define your artisan command cron schedule within your code (and therefore in version control), by updating the crontab as part of your deploy process.
PHP
1
star