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

Ccdn User Security Bundle Laravel Package

mikoweb/ccdn-user-security-bundle

A Symfony bundle that adds complete user account security: registration, login and logout, password reset, account confirmation by email, password strength rules, and role-based access control. It plugs into existing Symfony apps to handle common authentication workflows without building them from s...

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony2 bundle, not a Composer library you can drop into a Laravel app. If you're working in Laravel, treat it as a reference implementation of a pattern (login-failure throttling) rather than something you require. If you are on a legacy Symfony 2.8/3.x project, it is installable but abandoned — see Gotchas before committing.

Minimal steps (Symfony 2.8-era project):

  1. It is a companion to mikoweb/ccdn-user-bundle (the user/auth provider). You need that bundle installed and its login form/route working first — the security bundle hooks into that login flow. It will not do anything useful as a standalone package.
  2. composer require mikoweb/ccdn-user-security-bundle — check the fork's composer.json first; expect PHP 5.5+/Symfony 2.x constraints that will conflict with anything modern.
  3. Register the bundle in app/AppKernel.php:
    new CCDNUser\SecurityBundle\CCDNUserSecurityBundle(),
    
  4. Add config to app/config/config.yml under ccdn_user_security — the primary knobs are the login-failure tracking settings (max failures, reset window, block/ban behaviour). Copy the bundle's DependencyInjection/Configuration.php defaults rather than guessing keys.
  5. Update the schema: php app/console doctrine:schema:update --force (or generate a migration). This creates the LoginFailure table.
  6. Trigger a few bad logins and inspect the ccdn_user_security_login_failure rows.

Where to look first:

  • DependencyInjection/Configuration.php — the authoritative list of config keys and defaults.
  • Resources/config/services.yml — which listeners/subscribers are wired and their service IDs (this is how you override behaviour).
  • Entity/LoginFailure.php + repository — the tracked data model.
  • EventListener/ — where the auth events are intercepted.

First use case: cap repeated failed logins for a username/IP, block for a cooldown period, and purge old records. That's the whole scope — it does not do password policy, 2FA, or session hardening.

Laravel equivalent for the same use case: RateLimiter + the throttle middleware + Illuminate\Auth\Events\Failed, or just use Fortify/Laravel UI's built-in lockout (Auth::attempt with RateLimiter::tooManyAttempts). The concepts map one-to-one; the code does not.

Implementation Patterns

  • Two-axis counting. The useful design here is tracking failures by both username and client IP. Per-account counters stop targeted attacks; per-IP counters stop spraying. Copy both axes if you port the pattern. A single counter on either side is trivially bypassed.
  • Threshold + window + cooldown. The config model is "block after N failures; reset the counter after the window; block for the cooldown." Keep those three as separate values — conflating "how many" with "how long" is the most common config mistake.
  • Intercept the auth failure event. In Symfony, that's the security authentication events; the bundle's listener records the LoginFailure row and increments on repeat. In Laravel you'd mirror this on Illuminate\Auth\Events\Failed and Login (to reset counters):
    Event::listen(Failed::class, fn ($e) => LoginAttempt::record($e->credentials['email'], request()->ip()));
    Event::listen(Login::class, fn ($e) => LoginAttempt::clear($e->user->email, request()->ip()));
    
  • Gate the check before authentication, not after. The decision "is this identity locked out?" must run before password verification. Check RateLimiter::tooManyAttempts($key, $max) (or the bundle's repository lookup) at the top of the login controller/middleware.
  • Purge old rows. The entity accumulates forever without cleanup. Schedule a nightly delete of failures older than the window (a Symfony command in the original; in Laravel a scheduled job or a where('created_at', '<', now()->subHours(24))->delete()).
  • Override via service ID, not by editing vendor code. Symfony's DI makes the listener swappable in services.yml. If you need to change blocking behaviour, extend the listener class and redefine the service.
  • Return generic errors. Once throttled, respond identically to "wrong password" (or a fixed "try again in X" message) — don't leak whether the account exists or whether the lockout is per-user vs per-IP.
  • Progressive delays over hard lockout. The bundle's binary ban is simplest but easiest to abuse (see Gotchas). In a Laravel port, prefer RateLimiter::hit($key, $decaySeconds) with escalating decay plus a CAPTCHA challenge, rather than a permanent disable flag on the user row.
  • Test it. Functional tests that fire N failed login requests and assert the (N+1)th returns 429/blocked are the only reliable way to validate the wiring — a misconfigured listener fails silently.

Gotchas and Tips

  • It is effectively abandoned. Last release June 2016, 0 stars, 0 dependents, Symfony2 (EOL since 2018). There is no security-advisory coverage, no PHP 8 support, and the fork exists mainly to keep an old dependency installable. Do not introduce this into an auth-critical path of a new project; vendor the pattern into your own code instead.
  • It is not a Laravel package. No service provider, no facades, no Eloquent. Any "day-to-day leverage" here is architectural reference: failure table + event hook + threshold check + purge. Budget an afternoon to reimplement in Laravel; don't budget days trying to shoehorn a Symfony bundle in.
  • Schema/indexing matters. Add indexes on username, ip_address, and created_at. Without them, every login does a full table scan once the failure table grows — a self-inflicted DoS.
  • Account lockout is a DoS vector. An attacker who knows a username can lock real users out by spamming bad passwords. Mitigations: per-IP limits plus per-account, notify the user, cap lockout duration, and never permanently disable on failures alone.
  • IP spoofing / proxies. If you key on client IP, the value is untrustworthy unless trusted proxies are configured. In Symfony set framework.trusted_proxies; in Laravel configure TrustProxies middleware. Otherwise X-Forwarded-For is attacker-controlled and per-IP limits vanish.
  • Distributed brute force bypasses it entirely. Per-account counters don't stop credential stuffing from a botnet. Pair with a WAF, breached-password checks, and 2FA; this package alone is not "brute force protection," it's one layer.
  • Config key drift. Forked bundles frequently diverge from the upstream docs. Always read Configuration.php in that fork before copying examples from blog posts — the defaults may differ from what the README shows.
  • Silent no-op failure. If the bundle is registered but the login route bypasses the CCDN user bundle (e.g., you use a custom authenticator), the listener never fires. Verify by checking that LoginFailure rows actually appear after a failed login — don't assume registration = protection.
  • Extension point for cleanup: the repository is the right place to add purge/findRecent queries; keep them in the repository so you can swap the storage later without touching listeners.
  • If you must fork it forward: bump composer.json constraints to your Symfony LTS and PHP version, run the existing tests, and pin the fork by commit hash. Treat it like patching a vendored library, not like upgrading a maintained package.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager