zxf/security

Laravel / ThinkPHP 安全中间件 - 简洁、无缓存、低误报的请求拦截包

Maintainers

Package info

github.com/zhaoxianfang/security

pkg:composer/zxf/security

Statistics

Installs: 45

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.1.7 2026-05-26 09:16 UTC

README

Security's Logo

zxf/security - Laravel / ThinkPHP 安全中间件

PHP Laravel ThinkPHP License

简洁、高效、智能的跨框架安全防护中间件

同时支持 Laravel 11+ThinkPHP 8+,通过统一的桥接层自动适配当前运行框架。

特性

  • 14层安全防护 - 全面的安全检测体系,从URL路径到文件上传层层防护
  • 精准拦截 - 高危攻击(SQL注入、命令注入、路径遍历、NoSQL、SSTI、SSRF)严格拦截
  • SSRF检测 - 检测服务器端请求伪造攻击,包括内网IP、云元数据、危险协议等
  • 编码绕过检测 - 检测多重URL编码、UTF-8过度编码、空字节注入等绕过技术
  • CRLF/Header注入检测 - 检测HTTP头注入和响应拆分攻击
  • 智能识别 - 自动识别Markdown文档内容,代码块内的标签不会误拦截
  • 零缓存依赖 - 不使用Redis/Memcached,直接使用框架原生功能
  • 低内存占用 - 正则模式延迟加载,避免 php artisan optimize 内存溢出(v5.1+)
  • 高性能 - 单次请求处理耗时 < 1ms,支持预过滤快速跳过
  • CIDR支持 - IP黑白名单支持IPv4和IPv6网段格式(如 192.168.0.0/162001:db8::/32
  • 拦截回调 - 支持自定义拦截决策,实现动态放行策略
  • 自定义视图 - 支持自定义拦截页面,支持Blade视图/ThinkPHP模板/闭包/类方法
  • 安全响应头 - 拦截响应自动添加安全HTTP头(X-Content-Type-Options, X-Frame-Options 等)
  • 跨框架兼容 - 同一套代码支持 Laravel 11+ 和 ThinkPHP 8+(v6.1+)

快速开始

安装

composer require zxf/security

Laravel 配置

# 发布配置文件
php artisan vendor:publish --tag=security-config

编辑 .env

SECURITY_ENABLED=true
SECURITY_LOG_ENABLED=true
SECURITY_RATE_LIMIT_ENABLED=true
SECURITY_RATE_LIMIT_ATTEMPTS=60

Laravel 11+ 中间件注册(推荐)

由于 Laravel 11+ 调整了 Router::middleware() 的行为,ServiceProvider 的自动全局注册在 Laravel 11+ 下会降级为组级注册(web / api)。强烈建议在 bootstrap/app.php 中手动注册全局中间件,确保所有路由(包括非 web/api 路由)都受到保护:

// bootstrap/app.php
use Illuminate\Foundation\Configuration\Middleware;

->withMiddleware(function (Middleware $middleware) {
    $middleware->append(\zxf\Security\Middleware\SecurityMiddleware::class);
})

⚠️ Laravel 11+ 注意事项

  • bootstrap/app.php 手动注册是唯一可靠的全局中间件注册方式
  • ServiceProvider 仍会自动将中间件推入 webapi 组作为兜底
  • 如果存在 global 中间件组,也会自动推入

✅ 支持 Laravel 11、12、13

ThinkPHP 8+ 配置

  1. 发布配置文件

    vendor/zxf/security/config/security.php 复制到项目 config/security.php

  2. 注册中间件

    app/middleware.php 中添加:

    return [
        // ... 其他中间件
        \zxf\Security\Middleware\SecurityMiddleware::class,
    ];

    或者通过服务类自动注册(在 app/AppService.phpinit() 中):

    \zxf\Security\Providers\ThinkPHPSecurityServiceProvider::register($this->app);
  3. 配置环境变量

    ThinkPHP 下在 .env 中添加:

    SECURITY_ENABLED=true
    SECURITY_LOG_ENABLED=true
    SECURITY_RATE_LIMIT_ENABLED=true

📖 详细 ThinkPHP 使用指南:docs/thinkphp.md

内存优化(v5.1+)

本包默认正则模式已从配置文件迁移至独立数据文件,实现延迟加载

  • php artisan optimize 时不再加载任何正则模式 → 内存占用大幅降低
  • 正则仅在首次安全检测时按需加载(请求时),并由进程级缓存复用
  • 配置文件体积精简至原来的 ~30%,仅保留轻量配置参数

添加自定义检测模式:在配置中追加即可,会自动与内置模式合并:

// config/security.php
'high_risk_patterns' => [
    'sql' => ['/your_custom_sql_pattern/i'],
    'my_custom_type' => ['/custom_regex/i'],
],
'xss_patterns' => [
    'script' => ['/extra_xss_pattern/i'],
],
'url_path_detection' => [
    'path_patterns' => ['/custom_path_pattern/i'],
],

核心功能

功能 说明
IP白名单 可信IP跳过所有检查
IP黑名单 恶意IP直接拦截
URL路径攻击检测 直接检测URL中的路径遍历等攻击
多重编码检测 检测空字节、UTF-8过度编码、多重URL编码等绕过技术
User-Agent检查 封禁已知恶意扫描器
HTTP头检查 验证Host头、禁止的头信息、CRLF注入检测
请求体大小限制 防止内存溢出攻击
速率限制 防止暴力破解、CC攻击(IP+路由组合key)
SQL注入检测 UNION注入、堆叠查询、时间盲注、错误注入
命令注入检测 系统命令执行防护
路径遍历检测 ../../../etc/passwd
NoSQL注入检测 MongoDB等NoSQL数据库注入防护
SSTI检测 服务器端模板注入防护
SSRF检测 内网IP访问、云元数据、危险协议
CRLF/Header注入检测 HTTP头注入和响应拆分攻击
XSS防护 智能识别Markdown代码块
文件上传检查 禁止WebShell上传
安全响应头 拦截响应添加 X-Content-Type-Options 等安全头

拦截示例

# SQL注入 - 被拦截
curl "https://example.com/api?id=1' UNION ALL SELECT password FROM users--"
# → HTTP 403: 请求包含高危安全威胁

# 正常Markdown内容 - 放行
curl -X POST https://example.com/docs \
  -d 'content=```html<script>alert(1)</script>```'
# → HTTP 200: 请求通过

拦截回调(高级功能)

通过 before_block_callback 配置,你可以在拦截前执行自定义逻辑:

// config/security.php

'before_block_callback' => function(\zxf\Security\Dto\InterceptionContext $context) {
    // 1. 记录到数据库
    SecurityLog::create($context->toArray());

    // 2. 低风险请求自动放行
    if ($context->getRiskLevel() === 'low') {
        return false; // 放行
    }

    // 3. 特定IP段放行
    if (str_starts_with($context->clientIp, '192.168.')) {
        return false;
    }

    // 4. 发送告警(异步队列)
    SecurityAlertJob::dispatch($context);

    return true; // 拦截
},

回调返回值说明

返回值 行为
false 放行 - 请求继续处理
true / null 拦截 - 返回拦截响应给用户

InterceptionContext 对象

回调接收的上下文对象包含以下信息:

$context->threatType           // 威胁类型: sql, xss, command, blacklist...
$context->getThreatTypeDescription() // 中文描述
$context->getRiskLevel()       // 风险等级: high, medium, low
$context->clientIp             // 客户端IP
$context->method               // HTTP方法
$context->url                  // 请求URL
$context->matchedPattern       // 匹配的正则模式
$context->matchedContent       // 匹配的内容片段(脱敏)
$context->allThreats           // 所有检测到的威胁
$context->toArray()            // 转为数组格式

使用场景

  1. 动态放行策略 - 根据业务规则临时放行某些请求
  2. 威胁日志记录 - 将拦截事件记录到数据库或外部系统
  3. 实时告警通知 - 发送钉钉/企业微信/短信告警
  4. 威胁情报分析 - 收集攻击数据用于后续分析

自定义拦截页面

通过 response.view 配置自定义拦截视图:

方法1:使用 Blade 视图

// config/security.php
'response' => [
    'view' => 'errors.security',
],

创建视图 resources/views/errors/security.blade.php

<!DOCTYPE html>
<html>
<head>
    <title>访问被拒绝</title>
    <style>
        body { font-family: sans-serif; padding: 50px; text-align: center; }
        .alert { background: #fee; border: 1px solid #fcc; padding: 30px; border-radius: 5px; max-width: 600px; margin: 0 auto; }
        .threats { background: #f5f5f5; padding: 15px; margin-top: 20px; text-align: left; }
    </style>
</head>
<body>
    <div class="alert">
        <h1>🛡️ 访问被拒绝</h1>
        <p>{{ $message }}</p>
        @if(!empty($threats))
        <div class="threats">
            <strong>威胁类型:</strong> {{ implode(', ', $threats) }}
        </div>
        @endif
    </div>
</body>
</html>

方法2:使用闭包函数

'response' => [
    'view' => function($data) {
        // 根据威胁类型返回不同视图
        if (in_array('sql', $data['threats'])) {
            return view('errors.sql-injection', $data);
        }
        return view('errors.generic', $data);
    },
],

视图可用变量

变量 类型 说明
$message string 拦截提示消息
$blocked bool 是否被拦截
$threats array 威胁类型数组
$matched_pattern string 匹配的正则模式
$matched_content string 匹配的内容片段

文档

许可证

MIT License - 详见 LICENSE 文件