Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Password Exposed Validation Rule Laravel Package

jord-jd/laravel-password-exposed-validation-rule

A Laravel validation rule that checks passwords against the Have I Been Pwned database, helping you reject known-breached credentials during registration or password changes. Simple to add to form requests and validators.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require and let Laravel's package discovery register the service provider; publish the config only if you need to change timeout, cache, or fail-open behaviour.
  • Look first at the rule class itself (its passes() implementation) and the config file — the rule's behaviour on non-string input changed in v6.1.0 and is the single most important thing to understand before wiring it in.
  • The version floor is deliberately wide: PHP 7.4 / Laravel 8 through PHP 8.5 / Laravel 13. Confirm your own CI matrix spans both ends before adopting.
  • First use case: add the rule to the password field of a registration or password-change FormRequest, alongside Laravel's own string and length rules:
'password' => ['required', 'string', 'min:12', 'confirmed', new NotBreached()],
  • As of v6.1.0 the rule no longer warns about or converts non-string values — it defers them to Laravel's string/type rules. Compose accordingly from day one.

Implementation Patterns

  • Compose, don't replace. The intended pattern is the rule plus string (and Password::defaults() if you use it). The package explicitly documents this composition because the rule now tolerates non-string input rather than flagging it.
  • FormRequest is the natural home. Keep the rule out of controllers; apply it consistently across registration, password reset, and password change so policy doesn't drift. Consider a shared trait or a Password::defaults()-style factory method returning a consistent rule stack.
  • Value objects still work. Anything implementing __toString() is stringified and checked, so a Password DTO or a Stringable cast flows through unchanged — useful if you normalise input before validation.
  • Don't put it on login. Breach lookups add latency and can leak signal about stored credentials; restrict to creation/rotation flows.
  • Fake the transport in tests. Since the rule performs lookups, use Http::fake() (or the package's binding, if it exposes one) so your suite is hermetic. Assert both the passing and failing branch — that's what the new regression coverage in this release does upstream.
  • Mind caching. If results are cached by hash prefix, a repeated submission in a single request cycle may not re-hit the network; don't write tests that assume a call count unless you clear the cache between cases.
  • CI matrix. Run at least one job on PHP 7.4/Laravel 8 and one on PHP 8.5/Laravel 13; the wide floor means regressions can hide at either end.

Gotchas and Tips

  • Silent pass on non-strings is the upgrade trap. If you previously relied on the rule to reject arrays or integers (via its conversion warning), that safety net is gone. Pair with string or bail explicitly, or a malformed payload will satisfy this rule.
  • Conversion warnings disappeared. Anything alerting or log-scraping on those warnings will go quiet after upgrading; add an explicit string rule to catch the same input earlier and more clearly.
  • __toString() can throw. An object that is Stringable but throws during stringification will surface as an exception, not a validation failure. Guard or cast upstream if you accept arbitrary objects.
  • Nulls and empty strings are still handled by nullable/required; don't duplicate that logic in the rule stack.
  • Network failure policy matters. Check whether the config fails open (allows the password) or closed (rejects) when the lookup service is unreachable — the wrong default can lock every user out during an outage. Set an explicit timeout and decide deliberately.
  • Debugging a false rejection: log the hash prefix, not the password, and test the same value against the upstream API directly to separate "rule bug" from "genuinely breached".
  • Extension points: the HTTP client and cache store are typically container-bound — override them in a service provider for proxies, retries, or a Redis cache rather than forking the rule. Publish the lang file to customise the failure message.
  • Upgrading: no breaking changes in v6.1.0 and the floor is unchanged, so this is a drop-in. Re-run your suite on PHP 8.5 / Laravel 13 to catch deprecations, and add a test that a non-string payload is rejected by your own rule stack, since the package will no longer do it for you.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel