{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreidcwqkpzcxkpgkpej6h3ogicnomnsm4ux4ypnb7454tusjhf5h47e",
    "uri": "at://did:plc:anldby4lwneunjl777bq6ih7/app.bsky.feed.post/3mes5ebn4tiu2"
  },
  "coverImage": {
    "$type": "blob",
    "ref": {
      "$link": "bafkreicw5amrbjaj2luqvgjqtkfpdwuwrdrsozldlgegcagqefszswlgie"
    },
    "mimeType": "image/png",
    "size": 1379379
  },
  "description": "[Tip #125] routes/web.php is boring and reliable, and routes/api.php is fancy, but have you forgotten one?",
  "path": "/security-tip-consider-all-routes-not-just-web/",
  "publishedAt": "2026-02-14T04:05:12.000Z",
  "site": "https://securinglaravel.com",
  "tags": [
    "** _Security Tips_**",
    "_**In Depth** articles_",
    "_Laravel Security Audit and Penetration Test_",
    "_Security Reviews_",
    "_Bluesky_",
    "_other socials_",
    "_Practical Laravel Security_"
  ],
  "textContent": "A common pattern I see all the time is an `is_active` flag on a User record, with matching `EnsureUserIsActive` middleware on the `web` route or `auth` route group inside `routes/web.php`.\n\nAs you'd expect, this is used to prevent a User who has been deactivated from accessing the application. It's simple to implement, with minimal overhead in the code, and typically just works.\n\nHowever...\n\nThe routes inside `routes/web.php` aren't the only places where the user can interact with your application. There are typically two more you need to consider too:\n\n  1. API routes.\n  2. Broadcast channels.\n\n\n\nThe **API routes** inside `routes/api.php` are just fancy versions of what you've got inside `routes/web.php`. They even have their own Middleware stack too, so I'll often find `EnsureUserIsActive` has been added where it's needed, so the active user is properly checked.\n\nHowever, **Broadcast channels** don't have their own middleware, exist in the strange alternate universe of `routes/channels.php`, and all you've got to work with is this:\n\n\n    Broadcast::channel('App.Models.User.{id}', function ($user, $id) {\n        return (int) $user->id === (int) $id;\n    });\n\nDefault user channel auth callback.\n\nThe channel name often changes to something simpler, like `user.{id}`, but the conditional - that's usually all I find here.\n\n**Notice what's missing?**\n\nThe `is_active` flag is being completely ignored! This means that a user account can be deactivated and kicked out of the UI and the API, but still subscribe and listen to broadcast messages.\n\nWhat this exposes depends very much on what you send through your broadcast messages. However, there is the potential for significant information leakage in real-time applications that broadcast a lot of sensitive information and rely on flags like `is_active` to control user access.\n\n**In summary...**\n\nUltimately, my point here is that you need to consider **all routes** a user can interact with your application through, and ensure that any access control measures, like `is_active` flags, are checked across**all of them**.\n\nAnd don't forget about the humble `routes/channels.php`, it's just as important as `routes/web.php` and `routes/api.php`!\n\n* * *\n\n**_If you found this security tip useful?_ 👍**\n _Subscribe now_ _to get weekly_** _Security Tips_** _straight to your inbox, filled with practical, actionable advice to help you build safer apps._\n\n**_Want to learn more?_ 🤓**\n _Upgrade to a_ _Premium Subscription_ _for exclusive monthly_ _**In Depth** articles_ _, or support my work with a_ _one-off tip_ _! Your support directly funds my security work in the Laravel community._ 🥰\n\n _**Need a second set of eyes on your code?**\nBook in a __Laravel Security Audit and Penetration Test_ _today! I also offer budget-friendly_ _Security Reviews_ _too._\n\n_Finally, connect with me on_ _Bluesky_ _, or_ _other socials_ _, and check out_ _Practical Laravel Security_ _, my interactive course designed to boost your Laravel security skills._",
  "title": "Security Tip: Consider All Routes, Not Just Web!",
  "updatedAt": "2026-02-14T04:05:12.000Z"
}