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 Safe Request Laravel Package

michael-rubel/laravel-safe-request

A Laravel package for safer request handling: define validation rules and access only validated input, keeping unvalidated fields out of controllers and services. It helps reduce mass-assignment and untrusted-data risks while keeping form requests simple.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Unchanged. The package still targets a narrow, well-defined seam in Laravel: the FormRequest lifecycle, making validated data the default accessor surface via a trait. It remains additive, opt-in per request class, and requires no service provider, config, or middleware. It does not replace the validator; it changes what the validator's output is allowed to influence. Nothing in 2.0.1 touches this.

Integration feasibility. Materially improved. The prior assessment's main integration gate was a stale Composer constraint — a January 2023 release would most likely declare ^9.0 and fail resolution on Laravel 10. The 2.0.1 changelog explicitly adds Laravel 10 support, so the one-line composer require + use SafeRequest; path is now viable on Laravel 10 without an immediate fork. Two caveats remain: (1) Laravel 11 and 12 are still unaddressed, so the same fork-and-widen work is merely deferred to the next upgrade rather than avoided; (2) the release is a patch version, so confirm it widened the constraint rather than dropping Laravel 9 — narrowing a constraint in a patch release would be a semver violation and a signal about release hygiene. Also confirm the PHP constraint moved in step; a Laravel 10 constraint paired with php: ^8.0 is fine, but worth reading.

Technical risk. The lifecycle component of the risk drops from "high" to "moderate"; the behavioral component is unchanged and now the dominant concern:

  • Lifecycle status: dormant, not dead. A release landed, which contradicts the "archived, no upstream" characterization in the prior assessment. But one release after a ~2.5-year gap is a signal of low cadence, not of active maintenance. Still single maintainer, still no dependents, still in the low-double-digit star range. Treat as "alive but uncommitted" — you cannot infer a security-response capability from a compatibility bump.
  • Silent semantic change. Unchanged and still the top risk. Making validated input the default narrows what every consumer of that request object sees. Code paths that legitimately read non-validated fields — file uploads, merge()-injected values, route/query parameters accessed through the same object, input() on keys absent from the rules array — will begin returning null rather than data. Failures here are quiet, not loud.
  • Behavioral surface is small but undocumented in detail. Which methods are overridden matters a great deal. validated() semantics for nested/optional keys, wildcard rules, and sometimes rules are exactly where narrowing surprises appear. Nothing in the changelog suggests the override list changed, but "no entry in the changelog" is not evidence — read the 2.0.0...2.0.1 diff and confirm it is composer.json plus CI only.
  • Reimplementation cost is still near zero. Roughly a dozen lines in an in-house trait. The build-vs-buy calculation has shifted, but not decisively: buying now costs one Composer line on Laravel 10 instead of a fork, which is genuinely cheaper — until the next Laravel major, at which point you fork anyway.

Key questions.

  1. Which methods does the trait actually override — all() only, or also input(), only(), get(), __get(), merge()? Is the override list exhaustive and stable?
  2. What are the declared composer.json constraints for PHP and illuminate/* in 2.0.1? Did the release widen to ^9.0|^10.0 or drop ^9.0? Did the PHP constraint change?
  3. Does the 2.0.0→2.0.1 diff contain any source changes outside composer.json, CI, and the README? Any change to the trait's override list or return semantics must be treated as a behavioral change regardless of version number.
  4. Is there any stated position from the maintainer on Laravel 11/12, or is this a one-off compatibility bump? Absent a roadmap, plan for the next major to require a fork.
  5. Does it break $request->file() access, $request->route() parameters, or values injected via merge()/middleware?
  6. How does it handle wildcard, sometimes, and nullable rules — does a key absent from the rules array vanish entirely?
  7. Is there a test suite in the repo we can read to confirm the intended contract, and does CI now run against Laravel 10 specifically (a matrix entry is worth more than a constraint bump)?
  8. Are there any published security advisories or open issues describing data-leak or bypass behavior?

Integration Approach

Stack fit. Unchanged. Suitable only for applications that (a) already route all controller input through FormRequest and (b) read request data in controllers/services via the request object rather than via validated() assigned to a DTO. Applications that already call $request->validated() explicitly — or that map to DTOs/VMs — gain almost nothing and take on behavioral risk for no benefit. The package's value is essentially "enforcement for teams that forget to call validated()."

Migration path. The fork is no longer the forced route on Laravel 10, but it remains the recommended one for anyone planning to stay on Laravel past the next major. The choice is now time-horizon dependent:

  1. Dependency (now defensible on Laravel 10). composer require michael-rubel/laravel-safe-request, add the trait. Justified if the team is on Laravel 10, the repo has characterization tests per overridden method, and someone owns re-evaluating at the Laravel 11 upgrade. Accept that the fork happens later rather than never.
  2. Vendor the trait (still recommended for anyone on Laravel 10 who values certainty, and required for Laravel 11+). Copy the trait into app/Http/Requests/Concerns/, add MIT attribution, widen constraints in-house. Cost is minutes; it removes abandonware risk entirely, gives us ownership of the override list, and lets us add our own tests. Because the package is MIT and dependency-free, this is legally and technically clean.

If the team's actual objective is "stop unvalidated fields reaching Eloquent," an equivalent outcome is achievable through stricter discipline ($request->validated() at every call site, or a FormRequest::toDto() convention) without any new abstraction. The trait's real benefit is default-safe behavior for new contributors — worth having, and now cheaper to try before owning.

Compatibility. Laravel 10 is claimed supported as of 2.0.1; verify rather than assume. Confirm CI actually exercises Laravel 10 (matrix entry, not just a constraint), then verify against the target minor the team runs. Laravel 11/12 remain unsupported by declaration and must be treated as fork-required. Pin an explicit test matrix: one test per overridden method, per Laravel minor version we support.

Sequencing.

  1. Read the 2.0.0→2.0.1 diff and confirm no source changes beyond dependency metadata; read the repo's tests and trait source; document the exact override contract in an ADR.
  2. Decide dependency-vs-vendor on time horizon: dependency is acceptable if Laravel 10 is the near-term target and a fork at Laravel 11 is pre-accepted; vendor now if the team wants to skip the re-decision.
  3. Add characterization tests for every overridden method, including nested, wildcard, sometimes, and file-upload cases. Write these before adoption either way — they are the artifact that survives whichever route you pick.
  4. Pilot on one bounded controller or one request class in a non-critical path; assert route params, files, and merge() behavior explicitly.
  5. Broaden to the full request layer behind a feature flag or per-request-class adoption, so rollback is a one-line revert per class.
  6. Add a lint/static-analysis rule nudging new FormRequest classes to include the trait, so adoption is enforced rather than remembered.

Operational Impact

Maintenance. Downgraded but not eliminated. A release exists and Laravel 10 resolves, so the immediate "will this install?" tax on the current stack is gone. The structural problem remains: one release in roughly two and a half years means no PHP minor-version bumps, no proactive compatibility work, and no security response. Under a Composer dependency, the tax recurs at every framework upgrade — the question is now "when," not "whether." Under a vendored trait, maintenance drops to near zero, but ownership is 100% ours, including a test matrix. Budget a few hours per Laravel major upgrade to re-verify the override list against upstream changes either way.

Support. Unchanged and still the weakest dimension. No maintainer SLA, no issue triage commitment, no stated release cadence. 2.0.1 demonstrates the maintainer is reachable but does not establish an obligation to respond. Internal support means whoever adopts it becomes the de facto owner — acceptable for a 15-line trait, uncomfortable for a dependency on the input trust boundary.

Scaling. Runtime impact is effectively nil: no service provider boots, no I/O, no config lookups; the trait only changes which in-memory array is read. It scales linearly with request volume like any other method delegation. The scaling concern is organizational — the more request classes adopt it, the larger the surface a single behavioral change (or framework change) affects at once. Adoption should remain incremental for that reason.

Failure modes.

  • Silent data loss (highest likelihood). A field read through the request object but not present in the rules array returns null; consumers may persist defaults or nulls without error. Symptom is wrong data, not an exception. Unchanged by the release.
  • Silent no-op. Trait overrides a parent method that a newer Laravel no longer calls, so the safety guarantee quietly disappears while tests still pass. Guard with explicit tests per overridden method. Now the most likely failure mode, since the package is being carried forward into a framework major it was not originally written for.
  • Fatal on upgrade. Method signature drift between the trait and the framework's Request class produces a hard error at class load — loud, and caught quickly. This is the failure mode you will hit at Laravel 11.
  • Installation failure at composer install. Deferred, not removed. Low severity, discovered at build time, but it blocks upgrades until addressed — expect it at Laravel 11.
  • Peripheral access breakage. File uploads, route parameters, and middleware-merged values not surfaced through the validated set; typically caught in staging if tested, missed if not.
  • Trust-boundary regression. If the trait is assumed to be a security control and it silently narrows or fails open, teams may relax explicit validated() discipline elsewhere. The trait is a safety default, not a security boundary — treat it that way.
  • False signal of active maintenance (new). A compatibility release after a long gap can read as "this project is alive and will track Laravel." Nothing in 2.0.1 commits the maintainer to that. Do not let the release reset the team's expectation of support without an explicit roadmap.

Ramp-up. Very low. Any Laravel developer understands FormRequest and traits; the concept is explainable in a paragraph ("the request object now only exposes validated fields"). The ramp-up cost is documentation, not training: the two things that must be written down are (1) which methods are overridden, and (2) how to access intentionally-unvalidated data (route params, files, headers) when the trait is in place. Without (2), new contributors will hit confusing nulls and work around the trait rather than with it. Add a third now: (3) the package's support horizon, so nobody assumes Laravel 12 works because 10 does.

Verdict (revised). 2.0.1 removes the objection that blocked adoption outright and shifts the recommendation from "the package is not [worth adopting]" to "adopt, but budget for ownership." The dependency is now defensible on Laravel 10 for teams with characterization tests and a named owner; vendoring the MIT trait remains the better call for teams on Laravel 11+, teams that want to decide once rather than twice, and any team that reads "one release in two and a half years" as the operative fact rather than "Laravel 10 is supported." The behavioral risk — silent narrowing on the input trust boundary — is unchanged by this release, so the mitigation that matters is still the per-method test matrix, not the constraint line. Re-evaluate on the next Laravel major or if a security advisory appears, whichever comes first.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core