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

Pass Security Bundle Laravel Package

nidhognit/pass-security-bundle

A password security bundle for PHP applications that validates credentials against configurable strength rules and compromised-password checks. Drop it into registration and password-change flows to enforce safer passwords with reusable validators and simple configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

First, confirm the stack mismatch. Despite the Laravel framing, nidhognit/pass-security-bundle is a Symfony bundle, not a Laravel package — it ships with a *Bundle class, DependencyInjection/Extension.php, and service definitions meant for Symfony's container. There is no service provider, no facade, and no Laravel auto-discovery. If you are strictly on Laravel, you will not "install and use" this; you will read its checker logic and port it into a small standalone class (see Implementation Patterns).

If you are on Symfony (or a Laravel project that already hosts a Symfony container for some reason):

  1. Install and pin. Last release was 2018-05-26, so constrain the version explicitly and check PHP compatibility against your runtime:

    composer require nidhognit/pass-security-bundle
    
  2. Register the bundle manually. There is no Flex recipe. Symfony 4+: add to config/bundles.php:

    Nidhognit\PassSecurityBundle\NidhognitPassSecurityBundle::class => ['all' => true],
    

    Symfony 3 / legacy: $bundles[] = new Nidhognit\PassSecurityBundle\NidhognitPassSecurityBundle(); in AppKernel.php.

  3. Look here first, in this order:

    • DependencyInjection/Configuration.php — the actual config keys and defaults (length, character classes, dictionary checks, thresholds).
    • Resources/config/services.* — the service ID you inject. This is the only reliable way to know the checker's public method names.
    • DependencyInjection/*Extension.php — how config maps onto the service (constructor args vs. setter calls).
    • Validator/ (if present) — a Symfony Constraint + ConstraintValidator you can drop directly onto a form field.
  4. First use case: reject weak passwords at registration. After registering the bundle and copying the default config, inject the checker service into your registration controller and call its check method, e.g.:

    public function register(Request $request, /* checker service */ $checker): Response
    {
        $password = $request->request->get('password');
    
        if (!$checker->check($password)) {      // confirm method name in the service class
            // surface a validation error, do not 500
        }
    
        // only now: password_hash($password, PASSWORD_DEFAULT)
    }
    

Do not treat a false return as an exception path — surface it as a normal form validation error.

Implementation Patterns

Inject the service, don't new it. The value of the bundle is the DI wiring plus config; instantiating the checker class yourself bypasses both. Autowire by the service ID if the class is not autowirable:

# config/services.yaml
services:
    App\Controller\RegistrationController:
        arguments:
            $passwordChecker: '@<service.id.from.services.yml>'

Prefer the Validator constraint if one ships. A Symfony Constraint lets you attach the rule declaratively and get it rendered by the form error mapper for free:

$builder->add('plainPassword', RepeatedType::class, [
    'constraints' => [new NotWeakPassword()], // name per the bundle's Validator/ dir
]);

This is the pattern that survives refactors; controller-level checks tend to get copied inconsistently across login, reset, and invite flows.

Centralize the policy. Register a single application-level PasswordPolicy service that wraps the bundle's checker and your own rules (common-password dictionary, email/username reuse, haveibeenpwned-style checks). Call sites then depend on your interface, not the bundle — which is what makes the eventual removal (this package is unmaintained) a one-file change.

Registration flow, end to end:

  1. Validate shape (length/character classes) — cheap, synchronous.
  2. Run the bundle's checker for dictionary/entropy.
  3. Run any breach-list check (external, cacheable — see Gotchas).
  4. Only then password_hash() and persist. Never store or log the plaintext.

Live-strength endpoint. Expose a small authenticated, rate-limited controller that runs the checker and returns a score/label as JSON for the signup form. Keep the authoritative check server-side on submit; the AJAX endpoint is UX only and must not be trusted.

Testing pattern. Because the bundle likely ships zero tests, pin behavior with your own data-provider test around the wrapper:

/**
 * @dataProvider weakPasswords
 */
public function testRejectsWeak(string $password): void
{
    self::assertFalse($this->policy->isAcceptable($password));
}

public static function weakPasswords(): array
{
    return [['password'], ['123456'], ['qwerty'], /* ... */];
}

Laravel adaptation. If you cannot run the Symfony container, extract the checker class from the bundle (it is typically a plain PHP object with a couple of constructor scalars) into app/Support/PasswordSecurity, bind it in a PasswordSecurityServiceProvider, and expose it via a custom Rule object implementing Illuminate\Contracts\Validation\Rule. That gives you Laravel-idiomatic validation ('password' => ['required', new NotWeakPassword]) with the bundle's logic and none of its framework baggage.

Gotchas and Tips

  • Symfony-only, effectively unmaintained. Score 0.085 / 11 stars / last release 2018-05-26 / 0 dependents. Treat it as a code reference, not a long-lived dependency. Budget for a fork or in-house replacement.
  • No Flex recipe and no auto-discovery. Manual bundles.php registration is the #1 cause of "service not found" on first install.
  • Service ID is not the class name. Read Resources/config/services.* before trying to autowire. If the service is private (Symfony 4+ default), you must alias it or inject by ID; $container->get() will throw.
  • Config keys are undocumented outside Configuration.php. Don't guess names — read the tree builder. Unknown keys silently fail or throw depending on ignoreExtraKeys, which makes YAML typos painful to debug.
  • PHP version drift. 2018-era code commonly trips PHP 8.x deprecations (implicit nullable params, dynamic properties) and older Symfony DI signatures. Pin Symfony/PHP in CI and run the deprecation log before upgrading.
  • Never log the input. Password checkers are an obvious place to accidentally dump plaintext into Monolog via a caught exception's context. Wrap in try/catch and scrub.
  • External calls belong off the request path (or behind a cache). If the checker reaches a breach API, put a short-TTL cache in front of it and use a circuit breaker; a synchronous third-party call inside registration will take down signups when it's slow.
  • Decorate, don't fork, to extend. Add your own rules with decorates: <service.id> in Symfony and keep the original as the inner service — that composes cleanly and keeps the upgrade/removal path simple.
  • Return-value semantics are ambiguous. Confirm whether a falsy result means "weak", "invalid", or "error". Wrap it in a PasswordPolicy::isAcceptable(): bool and never let the raw return value leak into controllers.
  • Rate-limit any public strength-check endpoint. It is an unauthenticated oracle for password guessing if exposed without throttling.
  • Hash after the check, always. No checker guarantees strength; password_hash with PASSWORD_DEFAULT and a needsRehash upgrade on login are non-negotiable.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core