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 Needs Auto Rehash Laravel Package

samasend/laravel-needs-auto-rehash

Laravel Needs Auto Rehash automatically detects outdated password hashes and rehashes them after successful login, keeping user credentials aligned with your app’s current hashing algorithm and cost settings with minimal configuration.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What it is. A small Laravel service provider that listens on the framework's authentication events and, when a successfully authenticated user's stored hash no longer matches the current hashing configuration (Hash::needsRehash), transparently rehashes the plaintext credential and persists the new hash. It replaces a 3–5 line block that Laravel's own starter kits (Breeze, Jetstream, Fortify) currently ask developers to write by hand in the login path.

Architecture fit. The design is idiomatic Laravel: event listener + service provider, auto-discovered, zero-config. It does not patch the framework, wrap the Hash manager, or replace the guard, which is the right shape for this concern and keeps blast radius small. The concern is genuinely cross-cutting (every authentication entry point — web login, API token issuance, password reset, impersonation), so an event-driven listener is a better fit than duplicating the check in each controller. Conceptually this is a good architectural match.

Integration feasibility. Technically trivial — one composer require, no config file, no migrations, no published assets. In practice, the binding constraint is the release timeline. Last release was 2023-02-20 and the repository is archived, so the illuminate/* constraints almost certainly stop at Laravel 9/10. On Laravel 11/12 expect a dependency-resolution conflict, and note that the reason this package is interesting — Laravel 11 raised the default bcrypt cost from 10 to 12 — is exactly the scenario it can no longer be trusted to run in. The package is functionally complete, but functionally complete is not the same as installable.

Technical risk. This is a security-adjacent package sitting directly on the credential path, and that raises the bar considerably:

  • Unmaintained security surface. No CVE response, no compatibility fixes, no maintainer to ask. Low exploit likelihood given the code volume, but a governance finding regardless of likelihood.
  • Silent failure is the default failure mode. Rehash failures, save failures, or a listener exception can interrupt or degrade login with no telemetry. A silent no-op is benign; a thrown exception on the auth path is a login outage.
  • Persistence semantics. Rehashing must write the hash field without clobbering concurrent user-model updates (updated_at, other columns, observers, audit columns). Whether the package does a targeted update() or a full save() is the single most important thing to read in source.
  • Correctness of the plaintext source. The mechanism depends on an auth event that carries the plaintext credential (Laravel's Validated/Attempting events do; Login does not). Verify the listener binds to an event that actually receives plaintext, and confirm it cannot fire on failed attempts.
  • Test coverage. 66 stars and an archived repo imply unknown coverage. There is no credible signal of CI or a test matrix against multiple Laravel majors.
  • Governance signal. A 0.225 composite score with an archived flag is the profile of a package to be learned from, not depended on.

Key questions to answer before any decision.

  1. Does the listener bind to an event that receives plaintext credentials, and is it explicitly scoped to successful authentication only?
  2. Does persistence use a targeted column update or a full model save(), and how does it behave with observers, updated_at, and concurrent writes?
  3. Are exceptions on the auth path caught and logged, or do they propagate and break login?
  4. What is the package's actual composer.json constraint set, and does it resolve against our target Laravel version without --with-all-dependencies hacks?
  5. Is there CI and a test suite we can inspect and, if needed, run ourselves?
  6. Build vs. vendor: the total functionality is on the order of 40–60 lines including tests. What is the cost of reimplementing it in-house versus the cost of forking and owning an archived dependency?
  7. Does our current framework version already handle rehash in the starter kit or a first-party path, making this redundant?

Assessment. The architecture is sound and the problem is real, but the artifact is not adoptable as a third-party dependency: archived status on a credential-path package is a hard stop for most security review processes. The correct TPM outcome is not "reject the idea" — it is "extract the pattern, reject the dependency." Use the package as a reference implementation and own ~50 lines internally.

Integration Approach

Stack fit. Excellent, in the narrow sense. It assumes nothing beyond Laravel's Hash facade and the event dispatcher, both stable across majors. There is no framework-internal coupling, no facade swapping, no middleware ordering dependency. Any Laravel application with a standard guard-based auth flow can host the logic.

Migration path — recommended: internal reimplementation, not adoption.

  • Phase 1 — Reference, don't require. Read the package source (it is MIT-licensed, so reading and adapting is permitted; retain attribution if code is copied verbatim). Extract the listener body and event binding.
  • Phase 2 — Write an AutoRehashPassword listener in-house. Bind to the auth event carrying plaintext credentials, guard on successful authentication, call Hash::needsRehash(), and persist the hash with a targeted forceFill(['password' => ...])->save() or a scoped query update. Wrap in try/catch that logs and swallows — a failed rehash must never fail a login.
  • Phase 3 — Test it properly. Feature tests covering: hash under old cost → logged in → hash upgraded; correct password still works after rehash; failed login does not trigger a write; listener exception does not break login; rehash does not clobber concurrent profile updates.
  • Phase 4 — Instrument. Emit a log line or counter on rehash so you can observe the migration wave (see Operational Impact) and prove the control is working.

If for organizational reasons a dependency is preferred, the only defensible option is a vendored fork under our own namespace with our own release cadence and compatibility pins — at which point the effort delta versus writing it ourselves is negligible, and you carry the maintenance anyway.

Compatibility. Do not composer require the upstream package against Laravel 11+. The illuminate/support constraint will not resolve, and forcing it risks installing a package the framework cannot autoload correctly. If forking, update constraints to ^10.0|^11.0|^12.0 and run the suite on each major in CI.

Sequencing. Do not do this as a standalone change. The natural trigger is a hashing-parameter change (cost factor bump, algorithm migration, HASH_DRIVER switch). Bundle the listener work into that same initiative so it ships with the change that makes it necessary, and so the rollout plan explicitly accounts for the write amplification it introduces. Ship listener first, verify on a canary cohort, then flip the cost parameter.

Blast radius. Contained to the auth path if implemented as described. Explicitly out of scope: rehashing admin-set passwords outside a user's own login, rehashing API tokens, and any attempt to rehash on behalf of users who never log in again (see below).

Operational Impact

Maintenance. As a dependency: unbounded and unowned — an archived repo generates no upgrades and answers no pages, so the maintenance burden is silently transferred entirely to us at the worst possible moment (a framework upgrade). As an internal ~50-line listener: near-zero, a routine code-ownership cost with no external dependency to track. This asymmetry is the core of the recommendation. Do not let a trivially small dependency become a supply-chain liability on the authentication path.

Support. No upstream support, no issue triage, no maintainer to escalate to. Internally, the listener is well within the competence of any mid-level Laravel engineer to debug — the mechanism is a single Hash::needsRehash call and a save. Failure diagnosis is straightforward if it is instrumented, which is why the logging requirement in Phase 4 is not optional.

Scaling — the significant operational consideration. After a cost-factor increase, every returning user whose hash predates the change triggers a synchronous write on their next successful login. Three consequences:

  • Database write amplification. A step change in write volume on the users table during the migration window, concentrated on login. Expect elevated row-level contention on users rows and increased updated_at churn, which can disturb anything keyed off that column.
  • Login latency. The rehash itself is the expensive part — raising bcrypt cost from 10 to 12 roughly doubles hashing work, and it lands on the login path where you are already hashing once for verification and now again for rehash. p99 login latency will visibly degrade for users in the rehash cohort.
  • Population skew. Users who never return never rehash. Legacy hashes persist indefinitely, which weakens the security benefit and means the migration never genuinely completes. Plan for a periodic offline sweep with forced password reset for stale accounts if the security goal requires full coverage.

Mitigation: canary rollout by cohort, stagger the parameter flip, watch DB write latency and login p99 during the window, and treat the listener as a no-op-after-convergence path so steady-state cost is one cheap needsRehash call.

Failure modes and mitigations.

Failure Impact Mitigation
Listener throws during login Login outage — highest severity try/catch, log, never propagate
Full-model save() clobbers concurrent writes Data loss on user record Targeted column update only; feature test for it
Rehash fires on failed authentication Wasted writes; potential info leak Guard on successful-auth event only
DB write fails / times out Login succeeds, hash not upgraded Accept and retry next login; log for visibility
No telemetry Migration progress invisible; silent no-ops Counter/log per rehash; dashboard the rate
Package unresolvable on newer Laravel Blocked framework upgrade Internal implementation removes this entirely

Ramp-up. Negligible for the internal approach — roughly half a day for an engineer familiar with Laravel's auth lifecycle, including tests and instrumentation; the conceptual payload is one well-known framework method. The reading time for the reference implementation is under an hour. Contrast with adopting the package: a security review that will almost certainly block on archived status, an unknown amount of source auditing to answer the persistence-semantics question, and a support argument that has no good answer.

Recommendation. Do not take a production dependency on an archived package on the credential path. Reimplement the pattern internally (MIT-licensed reference, ~50 lines, fully tested and instrumented), ship it alongside the next hashing-parameter change, and canary the rollout with explicit monitoring of login latency and users write volume. The package is a useful design reference and a poor operational commitment.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource