<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jayanta Kumar Nath</title>
    <description>The latest articles on Forem by Jayanta Kumar Nath (@jay123anta).</description>
    <link>https://forem.com/jay123anta</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3804044%2F138b1cad-18d6-4b88-a633-0cefa4660455.jpg</url>
      <title>Forem: Jayanta Kumar Nath</title>
      <link>https://forem.com/jay123anta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jay123anta"/>
    <language>en</language>
    <item>
      <title>I Built a Free Threat Detector for Laravel - Here's How It Works</title>
      <dc:creator>Jayanta Kumar Nath</dc:creator>
      <pubDate>Tue, 03 Mar 2026 14:22:55 +0000</pubDate>
      <link>https://forem.com/jay123anta/i-built-a-free-waf-for-laravel-heres-how-it-works-41b8</link>
      <guid>https://forem.com/jay123anta/i-built-a-free-waf-for-laravel-heres-how-it-works-41b8</guid>
      <description>&lt;p&gt;&lt;em&gt;Jayanta Kumar Nath — Updated March 2026&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I run a Laravel app that kept getting hit with SQL injection attempts, bot scanners, and random exploit probes. I didn't want to pay for a WAF service, so I built a middleware package that logs everything silently. It doesn't block anything - just watches, logs, and alerts.&lt;/p&gt;

&lt;p&gt;After sharing v1.1.0 here and on Reddit, I got some good feedback and spent time hardening it. v1.2.0 is out now with evasion resistance, queue support, and a bunch of fixes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What It Does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A middleware that sits in your Laravel pipeline, inspects every incoming request against 130+ regex patterns, and logs what it finds. It's a passive detector - it never blocks the request. Think IDS, not IPS.&lt;/p&gt;

&lt;p&gt;Detects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL injection (UNION, blind, stacked queries)&lt;/li&gt;
&lt;li&gt;XSS and script injections&lt;/li&gt;
&lt;li&gt;Remote code execution attempts&lt;/li&gt;
&lt;li&gt;Directory traversal, LFI/RFI&lt;/li&gt;
&lt;li&gt;Scanner bots (SQLMap, Nikto, Burp Suite, etc.)&lt;/li&gt;
&lt;li&gt;DDoS via rate-based detection&lt;/li&gt;
&lt;li&gt;SSRF, XXE, Log4Shell, LDAP injection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What's New in v1.2.0&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evasion Resistance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This was the big one. Regex-based detection is easy to bypass if you know how. Attackers use tricks like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;UNION/**/SELECT&lt;/code&gt; - SQL comment insertion to break up keywords&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;%2527&lt;/code&gt; - double URL encoding to sneak past filters&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CHAR(39)&lt;/code&gt; - SQL character encoding instead of literal quotes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;v1.2.0 adds a normalization layer that strips these tricks before matching patterns. The evasion attempt itself is also flagged separately as high severity. So you get two log entries: one for the evasion technique, one for the actual attack underneath.&lt;/p&gt;

&lt;p&gt;Also removed the old SQL Comment Syntax pattern (--, #, /*) - it was the #1 source of false positives. CSS classes like font--bold and CLI flags like --verbose were getting flagged. Real SQL attacks are still caught by the keyword patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Route Whitelisting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;New only_paths config - scan only specific routes instead of everything. Useful if you have a high-traffic app and only care about API endpoints or admin routes. Leave it empty (default) to scan all routes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Queue Support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;DB writes and Slack notifications can now be offloaded to a queue. Detection stays synchronous (so nothing is missed), but the write is deferred. Uses a dedicated StoreThreatLog job with 3 retries and backoff.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;THREAT_DETECTION_QUEUE=true&lt;br&gt;
THREAT_DETECTION_QUEUE_NAME=default&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto-Purge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Old threat logs can be automatically cleaned up on a daily schedule.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;THREAT_DETECTION_RETENTION=true&lt;br&gt;
THREAT_DETECTION_RETENTION_DAYS=90&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ThreatDetected Event&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every confirmed threat dispatches a ThreatDetected event. Hook into it for custom actions - Telegram alerts, SIEM feeds, blocklists, whatever you need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other Additions&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimum confidence threshold - ignore low-confidence noise (THREAT_DETECTION_MIN_CONFIDENCE)&lt;/li&gt;
&lt;li&gt;API rate limiting - auto-throttle on API routes&lt;/li&gt;
&lt;li&gt;Expanded LFI detection - added phar://, expect://, input:// protocols&lt;/li&gt;
&lt;li&gt;Full RFC 1918 private IP range - fixed 172.16.0.0/12 detection (was only matching 172.16.x.x)&lt;/li&gt;
&lt;li&gt;Localhost SSRF - added 0.0.0.0 to detection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stats queries reduced from 7-9 separate queries to 1 using CASE WHEN aggregation&lt;/li&gt;
&lt;li&gt;Fixed N+1 queries in coordinated attack detection&lt;/li&gt;
&lt;li&gt;Pattern validation cached per process lifecycle&lt;/li&gt;
&lt;li&gt;Content-type aware - skips binary fields in multipart uploads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Security Hardening&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSV export formula injection prevention&lt;/li&gt;
&lt;li&gt;Log injection prevention (strips control characters)&lt;/li&gt;
&lt;li&gt;SSRF prevention in geo-enrichment (IP validation before external API calls)&lt;/li&gt;
&lt;li&gt;Fixed 3 ReDoS-vulnerable regex patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Built-in Dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dark-mode dashboard with stats cards, 7-day timeline, searchable threat table, top offending IPs, and geo grouping. Uses Alpine.js + Tailwind CDN - no build step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12 API Endpoints&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Full REST API for stats, threat lists, IP rankings, country grouping, timelines, and CSV export. Plug into your own frontend or monitoring stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;86 tests, 338 assertions. Includes 16 full-cycle feature tests that send real HTTP requests through the middleware, write to the database, and verify the actual rows - not just unit-level pattern matching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;composer require jayanta/laravel-threat-detection&lt;br&gt;
php artisan vendor:publish --tag=threat-detection-config&lt;br&gt;
php artisan vendor:publish --tag=threat-detection-migrations&lt;br&gt;
php artisan migrate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the middleware in bootstrap/app.php (Laravel 11+):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-&amp;gt;withMiddleware(function (Middleware $middleware) {&lt;br&gt;
    $middleware-&amp;gt;append(\JayAnta\ThreatDetection\Middleware\ThreatDetectionMiddleware::class);&lt;br&gt;
})&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regex-based, not ML - won't catch novel zero-day patterns&lt;/li&gt;
&lt;li&gt;Passive only - detects but doesn't block&lt;/li&gt;
&lt;li&gt;No IP reputation database built in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What's Next&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Considering for future versions based on community feedback:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fail2ban export format&lt;/li&gt;
&lt;li&gt;Path-based probe tracking (404 probes to /wp-admin, /.env, etc.)&lt;/li&gt;
&lt;li&gt;Sensor class architecture for better extensibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/jay123anta/laravel-threat-detection" rel="noopener noreferrer"&gt;https://github.com/jay123anta/laravel-threat-detection&lt;/a&gt;&lt;br&gt;
Packagist: &lt;a href="https://packagist.org/packages/jayanta/laravel-threat-detection" rel="noopener noreferrer"&gt;https://packagist.org/packages/jayanta/laravel-threat-detection&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback welcome.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>security</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
