关于 laravel-owasp-security
面向 Laravel 13 应用的安全审计与编码规范技能,可对代码库执行 OWASP Top 10 检查,也可在功能开发时提供安全参考。检测到 React + Inertia.js 时还会加入相应检查。
主要功能
- 01OWASP Top 10 代码审计
- 02React + Inertia.js 安全检查
- 03按文件或功能限定审计范围
- 04输出问题位置与修复建议
- 05提供 Laravel 安全编码规则
适用场景
- 01发布前检查 Laravel 应用安全
- 02审查指定控制器或功能
- 03开发认证、支付或文件上传
- 04检查 Inertia 页面数据暴露
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ asyrafhussin/ agent-skills --skill laravel-owasp-security安装后在 Claude Code 中输入/laravel-owasp-security确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
AGENTS.mdmetadata.jsonREADME.mdrules/_sections.md_template.mdsec-authentication-rate-limiting.mdsec-broken-access-control.mdsec-cryptographic-failures.mdsec-csrf-protection.mdsec-inertia-data-exposure.mdsec-injection-prevention.mdsec-security-misconfiguration.mdsec-xss-react-inertia.md详细介绍
Laravel OWASP 安全
适用于 Laravel 13 + React/Inertia.js 应用的双用途安全技能。针对代码库运行完整的 OWASP Top 10 审计,或在构建功能时将其用作安全编码参考。
如何审计
第 1 步:检测技术栈
检查项目是否使用 React + Inertia.js,方法如下:
- 检查
app/Http/Middleware/HandleInertiaRequests.php是否存在 - 检查
resources/js/是否包含.tsx或.jsx文件 - 检查
composer.json中是否包含inertiajs/inertia-laravel - 检查
package.json中是否包含@inertiajs/react
如果检测到,请在报告开头说明:
"检测到 React + Inertia.js — 将同时应用 Laravel OWASP 检查清单和 React/Inertia 安全检查。"
如果未检测到,请说明:
"未检测到 React/Inertia.js — 仅应用 Laravel OWASP 检查清单。"
第 2 步:确定范围
- 如果提供了参数(
$ARGUMENTS):仅审查指定文件或功能 - 如果未提供参数:审查整个代码库
第 3 步:运行检查清单
逐项检查以下内容。对每项输出:
- PASS — 简要确认已验证的内容
- FAIL — 准确的
file:line、漏洞说明(请勿复现文件中的任何代码、值、API 密钥、令牌或 .env 内容),以及修复建议 - N/A — 如果该检查不适用于此项目
OWASP Top 10 检查清单
1. 失效的访问控制(A01:2021)
- 中间件按角色保护所有路由组(
auth、role:admin等) - 资源查询限定为已认证用户的数据 —
->where('user_id', auth()->id()) - 不存在未经所有权检查的直接对象引用
- 使用 Gate 和 Policy 授权资源访问
- 前端角色检查在服务端也有对应检查 — 绝不只依赖 React UI 检查
2. 加密失效(A02:2021)
- 使用
Hash::make()或'hashed'Eloquent cast 对密码进行哈希处理 — 绝不以明文存储 - 不使用 MD5 或 SHA1 对密码进行哈希处理
- 使用
Crypt::encryptString()或'encrypted'Eloquent cast 加密敏感字段(API 密钥、机密) -
APP_KEY足够长、随机且在每个环境中唯一 - 对敏感的一次性操作(密码重置、邮箱验证)使用签名 URL(
URL::signedRoute())
3. 注入(A03:2021)
SQL 与批量赋值:
-
whereRaw()、selectRaw()、orderByRaw()中不拼接字符串 — 使用?绑定 - 列名绝不根据未经白名单验证的用户输入生成
- 不将
$request->all()直接传给create()、fill()或update() - 不将未经验证的用户输入用于
forceFill()或forceCreate() - 模型显式定义
$fillable— 不使用$guarded = [] - 控制器在批量操作中使用
$request->validated()
XSS — Blade 与 React:
- Blade 模板中不使用
{!! $userInput !!}输出不可信数据 - 所有用户提供的 Blade 输出均使用
{{ }} - React 中不使用
dangerouslySetInnerHTML,除非先调用DOMPurify.sanitize() -
href和src属性不由未经验证的用户输入设置 - 不使用
eval()、new Function()或接收用户可控字符串的setTimeout(string) - 外部 CDN 脚本使用子资源完整性校验(
integrity="sha384-...")
4. 不安全的设计(A04:2021)
- 业务逻辑在服务端执行 — 绝不信任客户端输入的价格、总额和折扣
- 敏感操作需要二次确认(例如,删除账户前重新输入密码)
- 不存在缺少逐项授权检查的批量操作端点
- 仅限管理员使用的功能通过单独的中间件隔离 — 不只是从 UI 中隐藏
- 支付金额和报名状态由服务端计算,而非作为表单输入传递
5. 安全配置错误(A05:2021)
- 生产环境中设置
APP_DEBUG=false -
.env已添加到.gitignore,且从未提交 - 生产环境中的数据库使用受限用户,而非 root/admin
-
storage/和bootstrap/cache/的权限设置正确(不可对所有用户开放写入权限) - 已设置
APP_KEY,且各环境使用的值均不相同 - 对于经过身份验证的 API 路由,CORS
allowed_origins不是['*']
6. 易受攻击和过时的组件(A06:2021)
-
composer audit检查通过,不存在已知 CVE -
npm audit检查通过,不存在已知 CVE - Laravel 框架使用受支持的版本
7. 身份识别和身份验证失败(A07:2021)
身份验证:
- 使用 Laravel Breeze、Fortify 或 Jetstream,而非自定义身份验证实现
- 使用 bcrypt 或 argon2 对密码进行哈希处理(Laravel 默认方式)
- 登录路由已实施速率限制——使用
throttle中间件或在LoginRequest中使用RateLimiter - 密码重置和邮箱验证路由已实施速率限制
- 支付和敏感操作路由已设置适当的速率限制
- 成功登录后调用
session()->regenerate()
Cookie 和会话:
-
config/session.php中设置http_only = true -
config/session.php中设置same_site = lax或strict -
config/session.php中设置secure = true或null(HTTPS 时自动启用) -
lifetime设置为合理的值(大多数应用建议设置为 15–30 分钟) - 除非需要子域名,否则设置
domain = null -
EncryptCookies中间件已添加到 web 组中
8. 软件和数据完整性失败(A08:2021)
CSRF:
- web 组中已启用
VerifyCsrfToken中间件 - 仅将无状态路由(webhook、外部回调)排除在 CSRF 检查之外
- 所有非 Inertia POST 表单均使用
@csrf指令 - 已确认
validateCsrfTokens(except: [...])中排除的路由有合理依据
反序列化:
- 不使用
unserialize($request->input(...)) - 不使用
eval($request->input(...)) - 不使用
extract($request->all())
9. 安全日志记录和监控失败(A09:2021)
- 记录登录失败尝试及其 IP 和标识符
- 记录支付失败和异常
- 日志条目不包含明文密码或机密信息
- 已部署监控工具(Laravel Telescope、Sentry 或类似工具)
10. 服务器端请求伪造 — SSRF(A10:2021)
- 不使用
Http::get($request->input('url'))处理未经验证的 URL - 根据允许列表或方案检查验证用户提供的 URL
- 阻止用户提供的 URL 访问内部网络地址
其他检查项
不属于 OWASP Top 10,但对 Laravel 应用至关重要。
命令注入和危险函数
- 不将用户输入传递给
exec()、shell_exec()、system()、passthru() - 不存在开放重定向——不使用
redirect($request->input('url'))处理未经验证的 URL - 文件上传会验证
mimes:、max:——文件名绝不根据未经处理的用户输入生成
安全标头
- 已设置
Content-Security-Policy——如可能,使用 nonce(Vite::useCspNonce()) - 已设置
X-Frame-Options - 已设置
X-Content-Type-Options - HTTPS 已设置
Strict-Transport-Security - 已设置
Referrer-Policy - 已设置
Permissions-Policy
React + Inertia.js 检查项
仅在第 1 步检测到 React + Inertia.js 时运行。
R1. React 组件中的 XSS
- 使用
DOMPurify.sanitize()处理内容前,不使用dangerouslySetInnerHTML={{ __html: userInput }} -
href和src属性不得使用未经验证的用户输入——javascript:URL 会执行脚本 - 不使用
eval()、new Function()或setTimeout(string)处理由用户控制的字符串 - 验证用户输入中的链接方案(仅允许
https://或http://)
R2. Inertia.js 数据暴露(严重)
-
HandleInertiaRequests::share()不会暴露密码、令牌或仅供内部使用的标记 - 控制器使用
->only([...])或 API Resources,而不是原始模型的toArray() - 所有 Inertia props 都视为公开数据——初次加载时可在
data-pageHTML 属性中查看 - 绝不会将支付密钥和仅供管理员使用的凭据作为 Inertia props 传递
- 为包含敏感数据的页面启用 Inertia v2 历史记录加密
R3. Inertia.js 中的 CSRF
- 未禁用 Inertia 的
X-XSRF-TOKEN标头 - 如果绕过 Inertia 的路由器,自定义
fetch或axios调用会手动包含 CSRF 令牌 - 只有 Webhook/回调路由会被排除在 CSRF 保护之外
R4. React 中的身份验证状态
- Inertia prop
auth.user不包含密码哈希、记住我令牌和 2FA 密钥 - 在服务端执行角色/权限检查——React 检查仅用于 UI
-
auth.user仅包含 UI 实际需要的字段
R5. 浏览器中的敏感数据
- React 组件或 TypeScript 文件中没有硬编码的 API 密钥或机密
-
localStorage或sessionStorage中没有敏感数据——使用 HttpOnly Cookie -
VITE_*环境变量不包含机密——它们本质上是公开的
R6. 依赖项安全
-
npm audit检查通过,React 或 Inertia 包中没有高危/严重级别的 CVE - React 使用受支持的版本
- 已检查第三方组件库是否存在已知 CVE
输出格式
按以下结构编写审计报告:
## Laravel OWASP Security Audit Report
> React + Inertia.js detected — Laravel OWASP checklist AND React/Inertia security checks will both be applied.
### 1. Broken Access Control (A01:2021)
- **PASS** `app/Http/Middleware/RoleMiddleware.php` — role middleware applied to all route groups
- **FAIL** `app/Http/Controllers/PaymentController.php:42` — Payment model fetched without ownership check (direct object reference exposure). Fix: scope the query to the authenticated user.
[Continue for all 10 OWASP checks + Additional Checks + R1–R6 React/Inertia checks]
---
## Summary
### Critical Issues (fix immediately)
1. ...
### Warnings (fix soon)
1. ...
### Passed
X checks passed.
### Recommended Commands
composer audit
npm audit
何时参考指南
在以下情况下,请参考规则文件:
- 实现身份验证或密码处理
- 构建支付或 Webhook 集成
- 编写文件上传或下载逻辑
- 设计管理员或基于角色的访问控制
- 构建接收用户输入的 API 端点
- 在 React 组件中使用
dangerouslySetInnerHTML - 将数据从 Laravel 控制器传递到 Inertia props
按优先级划分的规则类别
| 优先级 | 类别 | 影响 | 规则文件 |
|---|---|---|---|
| 1 | 访问控制失效 | 严重 | sec-broken-access-control |
| 2 | 加密机制失效 | 严重 | sec-cryptographic-failures |
| 3 | 注入防护 | 严重 | sec-injection-prevention |
| 4 | XSS 与 React/Inertia | 高 | sec-xss-react-inertia |
| 5 | CSRF 防护 | 高 | sec-csrf-protection |
| 6 | 安全配置错误 | 高 | sec-security-misconfiguration |
| 7 | 身份验证与速率限制 | 高 | sec-authentication-rate-limiting |
| 8 | Inertia 数据暴露 | 高 | sec-inertia-data-exposure |
快速参考
1. 访问控制失效(严重)
sec-broken-access-control— 中间件、所有权检查、策略、范围查询
2. 加密机制失效(严重)
sec-cryptographic-failures— 密码哈希、加密转换、签名 URL
3. 注入防护(严重)
sec-injection-prevention— SQL 注入、批量赋值、原始查询绑定
4. XSS 与 React/Inertia(高)
sec-xss-react-inertia— dangerouslySetInnerHTML、DOMPurify、href/src 验证
5. CSRF 防护(高)
sec-csrf-protection— VerifyCsrfToken、Webhook 排除、Inertia CSRF
6. 安全配置错误(高)
sec-security-misconfiguration— APP_DEBUG、APP_KEY、安全标头、CORS
7. 身份验证与速率限制(高)
sec-authentication-rate-limiting— 限流、会话重新生成、防止暴力破解
8. Inertia 数据暴露(高)
sec-inertia-data-exposure— data-page 属性暴露、机密 props、API Resources
使用方法
阅读各规则文件,了解详细说明和代码示例:
rules/sec-broken-access-control.md
rules/sec-cryptographic-failures.md
rules/sec-injection-prevention.md
rules/sec-xss-react-inertia.md
rules/sec-csrf-protection.md
rules/sec-security-misconfiguration.md
rules/sec-authentication-rate-limiting.md
rules/sec-inertia-data-exposure.md
每个规则文件都包含:
- 带有元数据(标题、影响、标签)的 YAML frontmatter
- 该规则在 Laravel/React 环境中的重要性
- 附有说明的错误代码示例
- 附有修复方案的正确代码示例
- Laravel 13 和 PHP 8.3+ 的特定背景信息
完整编译文档
如需查看包含所有展开规则的完整指南:AGENTS.md
评论
支持 Markdown