psalm/psalm-plugin-laravel
GitHub: psalm/psalm-plugin-laravel
为 Laravel 提供静态分析与污点分析的安全扫描工具,可在不运行代码的情况下检测 SQL 注入、XSS 等漏洞。
Stars: 327 | Forks: 75
[](https://packagist.org/packages/psalm/plugin-laravel)
[](https://packagist.org/packages/psalm/plugin-laravel)
[](https://shepherd.dev/github/psalm/psalm-plugin-laravel)
[](https://github.com/psalm/psalm-plugin-laravel/actions/workflows/test.yml)
[](https://github.com/psalm/psalm-plugin-laravel/actions/workflows/test-laravel.yml)
# Laravel 的 Psalm 插件
内置安全扫描的 Laravel 静态分析工具。
唯一免费将深度 Laravel 类型分析与基于污点分析的漏洞检测结合的工具。
无需运行代码即可捕获 SQL 注入、XSS、SSRF、shell 注入、文件遍历和开放重定向问题。

## 安全扫描
插件附带 Laravel 特定的污点存根,可在整个代码库中跟踪用户输入从源头到汇点的流动。
与模式匹配工具不同,Psalm 跨函数边界跟踪数据流——捕获更简单的扫描器遗漏的漏洞。
```
// psalm-plugin-laravel catches this:
Route::get('/search', function (Request $request) {
$query = $request->input('q');
DB::statement("SELECT * FROM users WHERE name = '$query'");
// TaintedSql: user input flows directly to the SQL query
});
```
污点分析还适用于辅助函数、服务类和任意数量的调用层:
```
// Cross-function taint flow — pattern-matching tools miss this:
function getUserQuery(Request $request): string {
return "SELECT * FROM users WHERE name = '" . $request->input('name') . "'";
}
Route::get('/users', function (Request $request) {
DB::statement(getUserQuery($request));
// Psalm catches this: taint flows Request -> getUserQuery() -> DB::statement()
});
```
### 检测内容
| 漏洞类型 | OWASP | 示例 |
|-----------------|----------|---------------------------------------------------------------|
| SQL 注入 | A03:2021 | `DB::statement()`、`DB::unprepared()`、原始查询方法 |
| Shell 注入 | A03:2021 | `Process::run()`、`Process::command()` |
| XSS | A03:2021 | `Response::make()` 包含未转义内容 |
| SSRF | A03:2021 | `Http::get()`、`Http::post()` 使用用户控制的 URL |
| 文件遍历 | A01:2021 | `Storage::get()`、`File::delete()` 使用用户控制的路径 |
| 开放重定向 | A01:2021 | `redirect()`、`Redirect::to()` 使用用户控制的 URL |
| 加密误用 | A02:2021 | 跟踪加密/哈希污点逃逸和解密 |
安全扫描与类型分析一起自动运行——无需额外配置。
### 对比分析
| 工具 | Laravel 感知类型 | 污点分析 | 免费 |
|--------------------------|---------------------|--------------------|--------------------|
| **psalm-plugin-laravel** | 是 | 是(数据流) | 是 |
| Larastan | 是 | 否(PHPStan 不支持) | 是 |
| Enlightn Pro | 部分 | 否(基于规则) | 每个项目 99 美元+ |
| SonarQube | 通用 PHP | 是(通用) | 仅付费版本 |
| Semgrep | 仅 Pro 层级 | 基于模式 | 有限的免费层级 |
| Snyk Code | 通用 | 是(通用) | 混合模式 |
## 版本与依赖
维护的版本:
| Laravel Psalm 插件 | PHP | Laravel | Psalm | 状态 |
|----------------------|-------|-----------|-------|--------|
| 4.x | ^8.2 | 12, 13 | 7 | 稳定 |
| 3.x | ^8.2 | 11, 12 | 6 | 稳定 |
| 2.12+ | ^8.0 | 9, 10, 11 | 5, 6 | 旧版 |
(旧版 Laravel、PHP 和 Psalm 版本由插件 1.x 版本支持,但已不再维护)
有关支持的 PHP、Laravel 和 Psalm 版本的更多详细信息,请参阅 [发布说明](https://github.com/psalm/psalm-plugin-laravel/releases)。
从 v3 升级?请参阅 [v3 → v4 升级指南](docs/upgrade-v4.md)。
## 快速开始
### 步骤 1:安装
```
composer require --dev psalm/plugin-laravel
```
### 步骤 2:配置
如果之前没有在项目中使用过 Psalm,需要创建 Psalm 配置:
```
./vendor/bin/psalm --init
```
### 步骤 3:启用插件:
```
./vendor/bin/psalm-plugin enable psalm/plugin-laravel
```
### 步骤 4:运行
运行通常的 Psalm 命令:
```
./vendor/bin/psalm
```
安全污点分析作为 Psalm 7 标准分析的一部分自动运行。
无需额外标志。
### 步骤 5(现有项目):创建基线
在现有代码库上,首次运行可能会报告许多问题。
[基线文件](https://psalm.dev/docs/running_psalm/dealing_with_code_issues/#using-a-baseline-file) 允许您抑制所有当前问题,只关注新代码:
```
./vendor/bin/psalm --set-baseline=psalm-baseline.xml
```
从此处开始,逐步提高 `errorLevel`(从 4 开始,逐步降至 1)并随时间缩小基线。
## 配置
您可以使用 [XML 配置](https://psalm.dev/docs/running_psalm/configuration/) 和/或 [命令行参数](https://psalm.dev/docs/running_psalm/command_line_usage/) 自定义 Psalm 配置。
有关所有配置选项,请参阅 [docs/config.md](docs/config.md)。
## 自定义问题
该插件会发出超出 Psalm 内置检查的自定义问题:
- [NoEnvOutsideConfig](docs/issues/NoEnvOutsideConfig.md) — 在 `config/` 目录外调用 `env()`
- [InvalidConsoleArgumentName](docs/issues/InvalidConsoleArgumentName.md) — `argument()` 引用未定义的命令参数
- [InvalidConsoleOptionName](docs/issues/InvalidConsoleOptionName.md) — `option()` 引用未定义的命令选项
- [MissingView](docs/issues/MissingView.md) — `view()` 引用不存在的 Blade 模板(可选启用)
- [MissingTranslation](docs/issues/MissingTranslation.md) — `__()` 或 `trans()` 引用未定义的翻译键(可选启用)
- [ModelMakeDiscouraged](docs/issues/ModelMakeDiscouraged.md) — 使用 `Model::make()` 而非 `new Model()`
## 工作原理
它在后台读取 Laravel 对 facade 类上的原生 `@method` 注解,并根据 `Illuminate\Foundation\AliasLoader` 生成别名存根(包括来自您的 `config/app.php` 和包发现的别名)。它还附带手工制作的污点分析存根和特殊情况处理。
它还解析 SQL 架构转储(`php artisan schema:dump`)和 PHP 迁移文件,以推断数据库模型中的列名和类型。
## psalm-plugin-laravel 还是 Larastan?
**两者都用。** 它们解决不同的问题:
- **Larastan** 擅长 Laravel 特定的类型规则:`model-property` 验证、`view-string` 检查和 17+ 自定义规则。
- **psalm-plugin-laravel** 除了类型检查外,还提供基于污点的安全分析,这是 PHPStan 在结构上[无法提供](https://github.com/phpstan/phpstan/issues/8038)的,还包括对 auth guard、Eloquent 属性、作用域、属性等的深度类型支持。
Psalm 和 PHPStan 使用几乎相同的注解语法,因此它们可以并行工作而不会产生冲突。
**Larastan 检查您的类型。我们检查您的安全。两者都用。**
## 贡献
由 [@alies-dev](https://github.com/sponsors/alies-dev) 维护。
欢迎提交 PR 和 issue——首次贡献者也欢迎。
有 [贡献文档](docs/contributing/README.md) 可能帮助您(和您的代理)进行贡献。
特别需要帮助的领域:
- **污点分析覆盖** — 添加存根只需 5-15 行注解,即可保护数千个应用。请参阅[编写指南](docs/contributing/taint-analysis.md)。
- **Laravel 魔法(Eloquent、Facade、Collection)的类型推断**
- **强制执行 Laravel 最佳实践的新检查**
标签:CISA项目, DOE合作, ffuf, Laravel, OpenVAS, PHP, Psalm, SQL注入防护, Web安全, XSS防护, 云安全监控, 代码安全, 安全扫描, 时序注入, 漏洞枚举, 类型检查, 蓝队分析, 静态分析