惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
人人都是产品经理
人人都是产品经理
Engineering at Meta
Engineering at Meta
小众软件
小众软件
I
InfoQ
有赞技术团队
有赞技术团队
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Martin Fowler
Martin Fowler
月光博客
月光博客
雷峰网
雷峰网
aimingoo的专栏
aimingoo的专栏
云风的 BLOG
云风的 BLOG
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
V
Visual Studio Blog
博客园 - 叶小钗
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
GbyAI
GbyAI
P
Proofpoint News Feed
Apple Machine Learning Research
Apple Machine Learning Research

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Stop Scanners from Hammering Your PHP App — Without a Dat...
Benyamin Kha · 2026-05-16 · via DEV Community

Every day, automated bots are scanning your website. Not just yours — everyone's. They probe for exposed .env files, old WordPress admin panels, SQL injection points, and known CVEs. Some of them send thousands of requests per minute, not because they're targeting you specifically, but because scanning the entire internet is cheap and easy.

This article is about what's actually happening out there, why it matters even for small projects, and how a lightweight PHP library can help you deal with it.


What Are These Scanners, Exactly?

Web scanners are automated programs that crawl the internet looking for security vulnerabilities. Some are legitimate security tools — like Shodan or Censys — that map the internet for research purposes. But many others are operated by attackers who are looking for:

  • Exposed configuration files.env, web.config, .git/config
  • Unprotected admin panels/wp-admin, /phpmyadmin, /adminer
  • Known vulnerable endpoints — like xmlrpc.php in WordPress or setup.php left behind after an install
  • SQL injection and XSS vectors — via query strings, POST bodies, and cookies
  • Path traversal attacks — trying ../../etc/passwd variations

The tools they use are well-known: sqlmap, nikto, nmap, dirbuster, gobuster, masscan, and many more. These aren't obscure hacking tools — they're freely available, widely documented, and actively maintained.

Even if your app has no actual vulnerabilities, these scanners generate noise, consume server resources, pollute your logs, and can slow down real users during a burst of requests.


Why Server-Level Solutions Aren't Always Enough

You might wonder: "Can't Nginx or Apache handle this?"

Sort of. You can write firewall rules, block known bad IPs, or configure rate limiting in your server config. But these approaches have limitations:

  • They require system-level access (not always available on shared hosting)
  • They need manual maintenance as attack patterns evolve
  • They can't easily inspect request payloads for things like SQL injection signatures
  • They don't integrate naturally with your application logic

A PHP-level firewall runs inside your application, which means it can inspect everything: headers, query strings, POST bodies, cookies, request paths, and user agents — and react accordingly.


Introducing xZeroProtect

xZeroProtect is a lightweight, file-based PHP 8 firewall with zero external dependencies. No Redis, no MySQL, no external services — everything is stored on disk.

Introducing xZeroProtect layouts

Install it via Composer:

composer require webrium/xzeroprotect

Enter fullscreen mode Exit fullscreen mode

The simplest possible integration — two lines at the top of your index.php:

<?php
require 'vendor/autoload.php';

use Webrium\XZeroProtect\XZeroProtect;

XZeroProtect::init()->run();

Enter fullscreen mode Exit fullscreen mode

That's it. Default rules activate immediately.


What It Actually Does

1. Blocks Known Scanner User Agents

The library maintains a list of User-Agent signatures associated with scanning tools and attack frameworks: sqlmap, nikto, nessus, acunetix, masscan, dirbuster, gobuster, feroxbuster, wfuzz, ffuf, hydra, metasploit, and many others. Requests from these tools are blocked before they get anywhere near your application logic.

You can extend or trim this list:

$firewall->patterns->addAgent('custom-bad-bot');
$firewall->patterns->removeAgent('curl'); // if your API clients use curl legitimately

Enter fullscreen mode Exit fullscreen mode

2. Blocks Sensitive Path Probes

Scanners routinely probe paths that don't exist in modern PHP apps — and shouldn't. xZeroProtect blocks requests targeting:

  • CMS admin panels: /wp-admin, /wp-login, /administrator
  • Config files: .env, .git, .htpasswd, web.config
  • Database tools: /phpmyadmin, /adminer, /dbadmin
  • Dangerous files: .sql, .bak, .backup, dump.sql
  • Web shells: shell.php, c99.php, r57.php
  • Path traversal: ../, ..%2f, %2e%2e

If you're running a fully-routed PHP app with no .php files in URLs, you can add that as a rule too:

$firewall->patterns->addPath('.php');

Enter fullscreen mode Exit fullscreen mode

3. Scans Payloads for Attack Signatures

The payload scanner inspects GET parameters, POST body, raw input, and cookies using compiled regular expressions. It detects:

  • SQL injection variants: UNION SELECT, DROP TABLE, SLEEP(), BENCHMARK()
  • XSS: <script tags, inline event handlers, javascript: protocol
  • Path traversal: ../
  • PHP code injection: system(), exec(), eval(base64_decode(...))
  • LFI: /etc/passwd, /etc/shadow
  • Remote file inclusion
  • Command injection via shell metacharacters

4. Rate Limiting Without Redis

The rate limiter uses a sliding-window counter stored per-IP on disk. No Redis or Memcached required.

$firewall = XZeroProtect::init([
    'rate_limit' => [
        'max_requests' => 60,
        'per_seconds'  => 60,
    ],
]);

Enter fullscreen mode Exit fullscreen mode

When a client exceeds the limit, they accumulate violations. After enough violations, they get temporarily banned. After enough bans, permanently.

5. Doesn't Block Legitimate Crawlers

This is important: Google, Bing, and other legitimate search engines should not get caught in your firewall. xZeroProtect handles this with double-DNS verification for major crawlers:

  1. Resolve the visitor's IP to a hostname via reverse DNS
  2. Confirm the hostname ends with the expected suffix (e.g. .googlebot.com)
  3. Re-resolve that hostname back to an IP
  4. Confirm the re-resolved IP matches the original

Anyone can fake a User-Agent string. DNS cannot be faked. This is the same verification method recommended by Google and Bing in their official documentation.


Learning Mode: Test Before You Block

Before switching to production, you can run in learning mode. All threats are detected and logged, but nothing is blocked. This lets you review what would have been caught and tune your configuration accordingly.

// During tuning
XZeroProtect::init(['mode' => 'learning'])->run();

// Once satisfied
XZeroProtect::init(['mode' => 'production'])->run();

Enter fullscreen mode Exit fullscreen mode

This is genuinely useful. Running learning mode for a few days on a real server will show you the volume and variety of automated probes hitting your application — and help you avoid accidentally blocking legitimate traffic.


Apache Integration for Zero-PHP-Overhead Blocking

For permanently banned IPs, you can optionally write them into .htaccess so Apache rejects the connection before PHP even starts:

$firewall = XZeroProtect::init([
    'apache_blocking' => true,
    'htaccess_path'   => __DIR__ . '/.htaccess',
]);

Enter fullscreen mode Exit fullscreen mode

This is particularly useful for confirmed attackers who you never want to reach your application layer again.


Custom Rules

If the built-in modules don't cover a specific case, you can register your own:

use Webrium\XZeroProtect\RuleResult;

$firewall->rules->add('no-php-extension', function ($request) {
    if (str_ends_with($request->path(), '.php')) {
        return RuleResult::block('PHP extension not valid on this server');
    }
    return RuleResult::pass();
});

Enter fullscreen mode Exit fullscreen mode

Rules can block, log without blocking, or pass. They run in priority order and can be enabled, disabled, or removed at runtime.


What xZeroProtect Is Not

To be clear about expectations: this is not a commercial WAF. It won't stop a sophisticated, targeted attack from a determined adversary. It doesn't do deep packet inspection, it doesn't have a threat intelligence feed, and it doesn't update its rule set automatically.

What it does is significantly reduce the automated noise that hits most PHP applications — the opportunistic scanners, the script-kiddie tools, the mass-probing bots — with a setup that takes minutes and has no infrastructure dependencies.

For many projects, especially those on shared hosting or small VPS instances where you don't have the option to configure Nginx rate limiting or cloud WAF rules, this is a practical and useful layer of defense.


Getting Started

composer require webrium/xzeroprotect

Enter fullscreen mode Exit fullscreen mode

Full documentation and source: github.com/webrium/xzeroprotect

Start in learning mode, review your logs, tune your configuration, then flip to production.


Have feedback or found an edge case? Issues and PRs are welcome on GitHub.