一、技能概述
该技能为 Laravel 应用提供了一套完整的安全最佳实践参考,从认证授权到生产环境部署,系统化地覆盖了 Laravel 应用安全的各个维度。它既是一个安全检查清单,也是一个实操指南,帮助开发者在开发过程中识别和修复潜在的安全漏洞。
核心原则:安全防护应贯穿应用开发的每一个层面——从请求入口(中间件、表单请求)到业务逻辑(策略、授权)再到数据持久化(加密、批量赋值保护)。
二、核心功能
1. 身份验证与授权(Authentication & Authorization)
| 功能 | 说明 |
|---|---|
| API 认证 | 使用 Laravel Sanctum 或 Passport 进行 API 认证,优先使用短生命周期 token + 刷新流 |
| 路由保护 | 通过 auth:sanctum 中间件保护敏感路由 |
| Token 管理 | 登出时及账户受损时立即撤销 token |
| 密码安全 | 使用 Hash::make() 哈希存储,从不存储明文密码;使用 Password 规则强制密码复杂度(最少 12 位,含大小写字母、数字、符号) |
| 策略(Policies) | 使用模型策略进行细粒度授权,在控制器和服务中通过 $this->authorize() 应用 |
| 路由级授权 | 使用 can:update,project 中间件在路由层应用策略 |
// 路由保护示例
Route::middleware('auth:sanctum')->get('/me', function (Request $request) {
return $request->user();
});
// 策略授权示例
$this->authorize('update', $project);
Route::put('/projects/{project}', [ProjectController::class, 'update'])
->middleware(['auth:sanctum', 'can:update,project']);
2. 输入验证与数据净化(Validation & Sanitization)
-
始终使用 Form Requests 进行输入验证,从不信任请求 payload 中的派生字段
-
使用严格的验证规则和类型检查
-
使用 Laravel 的密码重置代理(password broker)处理重置流程
3. CSRF 防护
-
保持
VerifyCsrfToken中间件启用 -
在表单中包含
@csrf指令 -
在 SPA 请求中发送 XSRF token
-
对于 SPA + Sanctum 认证,确保
stateful域名已正确配置
4. 批量赋值保护(Mass Assignment)
-
使用
$fillable或$guarded属性明确定义可批量赋值的字段 -
避免使用
Model::unguard() -
优先使用 DTO 或显式属性映射
5. SQL 注入防护
-
使用 Eloquent 或查询构造器配合参数绑定
-
仅在绝对必要时使用原生 SQL,且必须使用参数绑定
DB::select('select * from users where email = ?', [$email]);
6. XSS 防护
-
Blade 默认转义输出(
{{ }}) -
仅在处理可信且已净化的 HTML 时使用
{!! !!} -
富文本内容使用专用净化库处理
7. 文件上传安全
| 检查项 | 说明 |
|---|---|
| 文件验证 | 验证文件大小、MIME 类型和扩展名 |
| 存储位置 | 尽可能将上传文件存储在公共目录之外 |
| 恶意软件扫描 | 如有必要,对上传文件进行病毒扫描 |
final class UploadInvoiceRequest extends FormRequest
{
public function authorize(): bool
{
return (bool) $this->user()?->can('upload-invoice');
}
public function rules(): array
{
return [
'invoice' => ['required', 'file', 'mimes:pdf', 'max:5120'],
];
}
}
8. 速率限制(Rate Limiting)
-
在认证和写入端点应用
throttle中间件 -
对登录、密码重置和 OTP 端点使用更严格的限制
RateLimiter::for('login', function (Request $request) {
return [
Limit::perMinute(5)->by($request->ip()),
Limit::perMinute(5)->by(strtolower((string) $request->input('email'))),
];
});
9. 密钥与凭证管理(Secrets & Credentials)
-
绝不将密钥提交到版本控制系统
-
使用环境变量和密钥管理服务
-
密钥暴露后立即轮换并使所有会话失效
10. 加密属性(Encrypted Attributes)
使用加密 casts 保护数据库中存储的敏感字段:
protected $casts = [
'api_token' => 'encrypted',
];
11. 安全标头(Security Headers)
通过中间件添加安全响应头:
| 标头 | 推荐值 |
|---|---|
Content-Security-Policy |
default-src 'self' |
Strict-Transport-Security |
max-age=31536000(仅当所有子域名均为 HTTPS 时添加 includeSubDomains/preload) |
X-Frame-Options |
DENY |
X-Content-Type-Options |
nosniff |
Referrer-Policy |
no-referrer |
12. CORS 与 API 暴露
-
在
config/cors.php中限制允许的来源 -
避免对已认证路由使用通配符来源
-
仅允许必要的 HTTP 方法和标头
13. 日志与 PII 保护
-
绝不记录密码、token 或完整支付卡数据
-
在结构化日志中脱敏敏感字段
Log::info('User updated profile', [
'user_id' => $user->id,
'email' => '[REDACTED]',
'token' => '[REDACTED]',
]);
14. 依赖安全(Dependency Security)
-
定期运行
composer audit -
谨慎锁定依赖版本,发现 CVE 后及时更新
15. 签名 URL(Signed URLs)
使用签名 URL 创建防篡改的临时链接:
$url = URL::temporarySignedRoute(
'downloads.invoice',
now()->addMinutes(15),
['invoice' => $invoice->id]
);
Route::get('/invoices/{invoice}/download', [InvoiceController::class, 'download'])
->name('downloads.invoice')
->middleware('signed');
三、主要用途
-
新项目安全基线 —— 在 Laravel 项目初始化时,参照此指南建立完整的安全防护体系
-
安全审计与代码审查 —— 在审查现有代码时,对照清单检查是否存在常见安全漏洞
-
生产环境加固 —— 部署前检查
APP_DEBUG=false、SESSION_SECURE_COOKIE=true、SESSION_SAME_SITE=lax/strict等关键配置 -
漏洞修复参考 —— 发现安全问题时,快速定位对应的防护措施和修复方法
-
团队安全培训 —— 作为 Laravel 开发团队的安全编码规范参考文档
四、重要原则
-
始终验证输入 —— 使用 Form Requests 和严格规则,永不信任用户输入
-
始终哈希密码 —— 使用
Hash::make(),永不存储明文密码 -
始终保护批量赋值 —— 使用
$fillable/$guarded,避免Model::unguard() -
始终使用参数绑定 —— 防止 SQL 注入
-
始终加密敏感数据 —— 使用加密 casts 保护存储中的敏感字段
-
生产环境关闭调试 ——
APP_DEBUG=false -
密钥永不入版本库 —— 使用环境变量管理
-
日志脱敏 —— 绝不记录密码、token 或 PII
五、总结
Laravel Security 是一个完整的 Laravel 应用安全最佳实践指南技能,覆盖从身份验证、授权、输入验证、CSRF 防护、批量赋值保护、SQL 注入/XSS 防御、文件上传安全、速率限制、密钥管理、加密属性、安全标头、CORS、日志脱敏、依赖安全到签名 URL 的 15 个核心安全领域。它既是一份可操作的安全检查清单,也是一套编码规范,适用于 Laravel 开发者在新项目初始化、安全审计、生产部署加固和团队安全培训等场景。