akaunting/laravel-firewall: a WAF layer built from Laravel middleware and route inspection
Web Application Firewall (WAF) package for Laravel
At a glance
- What is it?
- This package puts a set of pattern-matching middlewares in front of a Laravel application, blocks the requests that trip them, and reports attacks by email or Slack. It is easy to wire up with a publish tag and a migration, but it operates on request shape rather than on app semantics, and the README is thin on tuning.
- Who is it for?
- Adopt akaunting/laravel-firewall if you run a Laravel application that faces the public internet and want a first layer of request filtering plus attack notifications with little wiring. Do not treat it as your only defence, and do not adopt it if you need application-aware rules, because the filters are pattern matchers over request data and the whitelist middleware is IP based.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 160 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the package blocks and who it is for
The stated goal is to protect a Laravel application from a broad set of attack shapes, and the README names them directly: XSS, SQLi, RFI, LFI and User Agent abuse, among others. On top of that it blocks repeated attacks, sends a notification when an attack is detected, and separately records failed logins so an IP can be blocked after a number of attempts.
That is a WAF in the request-filtering sense, applied inside the application stack rather than in front of it. There is no reverse proxy, no separate daemon and no configuration file describing rules in a generic syntax. Everything happens in middleware, which is why the whole adoption path is one Composer command plus two artisan commands.
The audience is a team running a Laravel application that is already deployed and wants a visible, loggable layer of protection. The package is aimed at application owners, not at network teams, and it has no hardware or infrastructure footprint of its own.
The abstract Middleware class does the work dynamically
The most useful thing the README reveals about the design comes in a note rather than a section. Some middleware classes, the Xss one is named as an example, are empty, because the abstract Middleware class they extend does the job dynamically. The README puts it plainly: "they all works ;)".
In practice that means a middleware such as firewall.xss carries no bespoke detection logic of its own. Behaviour is driven by configuration and by the shared base class, so adding, removing or tuning a rule is a configuration exercise rather than a subclassing exercise. The flip side is that reading the source of one middleware tells you very little, and the configuration file is where the real decisions live.
The second consequence concerns the naming. The middleware aliases are short and friendly, firewall.xss, firewall.sqli, firewall.lfi, but the class behind them is not a general inspection engine. Each alias maps to a check with a fixed idea of what suspicious input looks like.
A three command install and a migration you own
Installation is the standard Laravel package flow. First the dependency, then the publish step that exposes configuration, language files and migrations under the firewall tag, then the migration that creates the tables the package writes to.
composer require akaunting/laravel-firewallphp artisan vendor:publish --tag=firewallphp artisan migrateThe publish step matters more than usual here, because after it the firewall's behaviour is set in config/firewall.php, and the README says you can change the firewall settings of your app from that file. The repository layout is small, with src/ and tests/ beside composer.json, phpunit.xml and a StyleCI configuration, which is consistent with a self-contained package rather than a framework-wide addon.
One thing the README does not document is a rollback story for the migration. If the tables need to come back out, that is left to your own migration discipline rather than to the package.
Applying firewall.all versus picking single middlewares
The middlewares are registered for you, so usage is route decoration. The catch-all is firewall.all, and the README explains exactly what it does: it applies all the middlewares available in the all_middleware array of the config file. That array, not the list of aliases, is the real definition of what the catch-all means.
Route::group(['middleware' => 'firewall.all'], function () {
Route::get('/', 'HomeController@index');
});For finer control you attach individual aliases. The README's example for an admin area is firewall.whitelist, which lets only whitelisted IPs reach the route.
Route::group(['middleware' => 'firewall.whitelist'], function () {
Route::get('/admin', 'AdminController@index');
});A third pattern is the one that most deserves attention, because it is easy to misread. Adding firewall.url to the inspections config does not block the request. The README says you can get notified when anyone not in the whitelist accesses admin by adding it to the inspections config, so a route protected by firewall.url becomes an observation point rather than a gate. The distinction between inspecting and blocking is a per-middleware decision, and it is the one most likely to surprise a team that assumed all aliases behave the same way.
The full alias list and what each one filters
The README enumerates the aliases you can attach to routes: firewall.all, firewall.agent, firewall.bot, firewall.geo, firewall.ip, firewall.lfi, firewall.php, firewall.referrer, firewall.rfi, firewall.session, firewall.sqli, firewall.swear, firewall.url, firewall.whitelist and firewall.xss.
Read as a group, the list shows three different kinds of check being mixed under one namespace. Some look at the request payload for injection signatures, the lfi, rfi, sqli and xss entries. Some look at request metadata, the agent, bot, geo, ip and referrer entries. Some look at session and URL structure, the session and url entries. firewall.swear sits apart entirely, being a word filter rather than an attack signature.
The README also says you may define routes for each middleware in config/firewall.php and apply that middleware or firewall.all at the top of all routes, which is the intended way to centralise coverage. Note that firewall.php, sitting among alias names that look like file extensions, is a filter name rather than a PHP handler, and firewall.geo depends on location data that the README does not describe.
Notifications that require real Laravel users
Detection triggers a notification immediately, and the delivery path has a documented precondition that trips people up. Emails entered in notifications.email.to must be valid Laravel users, in order for notifications to be sent. The README points at the Laravel Notifications documentation for the mechanism itself.
That is a deliberate design choice rather than an accident: the package reuses the framework's notification channel instead of shipping a mail transport of its own, which keeps the dependency footprint small but ties the firewall to your users table. A deployment where the firewall should report to a shared ops mailbox that has no user account will silently have no email path, and the Slack channel mentioned in the project description is the other route out.
The package also records failed logins and blocks an IP after a number of attempts, which means the tables created by the migration hold both attack events and authentication failure history. Retention is your problem, since the README does not describe a pruning job.
Version 3.0.0, an MIT licence and a gap since May
The release history shows 3.0.0 published on 2026-05-16, preceded by 2.3.0 in April 2025 and 2.2.0 in March 2024. A major version bump in a package that has been out for several years signals a compatibility change for Laravel applications, and the README points to the Releases page rather than describing what broke. That page is the place to check before upgrading an existing installation, since the README itself carries no upgrade notes.
Licensing is straightforward: MIT, with the licence text in LICENSE.md. No legal interpretation is needed for a permissive MIT package, though the licence covers this repository's own code rather than the behaviour of the application you protect.
On upkeep, the last push was on 2026-05-16. That is the date to anchor any decision about relying on new fixes, and it is worth weighing against a 3.0.0 that is now the only recent feature work on the branch. Contributors are asked to follow PSR coding standards, and StyleCI plus a GitHub Actions workflow for tests appear in the repository.
Editorial conclusion
Adopt akaunting/laravel-firewall if you run a Laravel application that faces the public internet and want a first layer of request filtering plus attack notifications with little wiring. Do not treat it as your only defence, and do not adopt it if you need application-aware rules, because the filters are pattern matchers over request data and the whitelist middleware is IP based. Before going live, publish the config with php artisan vendor:publish --tag=firewall, run the migration, and read config/firewall.php to see which middlewares firewall.all actually applies, since the middleware list is built from that array.
Frequently asked questions
How do I install akaunting/laravel-firewall?
Run composer require akaunting/laravel-firewall, then publish the package assets with php artisan vendor:publish --tag=firewall, then create the tables with php artisan migrate.
What does the firewall.all middleware actually apply?
It applies every middleware listed in the all_middleware array of config/firewall.php, so the array in the config file defines the real coverage of the catch-all.
How do I restrict access to an admin route to whitelisted IPs?
Wrap the route in a group that uses the firewall.whitelist middleware, as in the README example for the /admin route, and add the allowed addresses to the whitelist in config/firewall.php.
Why are no emails arriving from akaunting/laravel-firewall?
The addresses in notifications.email.to must be valid Laravel users, otherwise the notification cannot be sent. The README refers to the Laravel Notifications documentation for the delivery details.
Does the akaunting/laravel-firewall middleware block the request or just report it?
It can do either, depending on configuration. The README describes adding firewall.url to the inspections config so that access by anyone not in the whitelist triggers a notification rather than a block.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/akaunting-laravel-firewall)Was this useful?