本文目录导读:

为PHP项目做代码审计是一项系统性的工作,需要结合自动化工具与手动审查,以下是针对PHP项目安全审计的完整方法论,涵盖常见漏洞、检测技巧及最佳实践:
审计前的准备工作
-
环境搭建:
- 本地化部署: 将PHP项目及其依赖(如MySQL、Redis、Composer包)完整运行在本地或隔离的容器中。
- 开启错误报告: 在
php.ini中设置display_errors = On并设置error_reporting = E_ALL,便于发现潜在错误。 - 启用Xdebug: 用于单步调试和变量跟踪。
-
工具准备:
- 静态分析工具:
- RIPS(已停止维护但经典): 适合PHP历史项目。
- Phan / PHPStan / Psalm: 代码质量检查,也能发现部分类型相关漏洞。
- SonarQube + PHP插件: 全面代码质量和安全问题扫描。
- Semgrep: 规则驱动的轻量级静态分析。
- 依赖检查工具:
composer audit(用于发现已知漏洞的第三方包)、Snyk、OWASP Dependency-Check。 - IDE/编辑器集成: PhpStorm(内置代码检查和PSR规范)、VS Code + PHP Intelephense。
- 静态分析工具:
-
获取代码结构:
- 理解项目使用的框架(Laravel、ThinkPHP、Symfony、Yii等)或原生开发模式。
- 识别入口文件(
index.php、router.php、public/)。 - 查看依赖管理文件(
composer.json、package.json、composer.lock)。
核心审计清单:以漏洞类型为导向
SQL注入
- 检查点:
- 原生SQL写法(最危险):
mysqli_query("SELECT * FROM users WHERE id = " . $_GET['id'])。- 修复: 强制使用参数化查询(PDO的
prepare/execute或 MySQLi的bind_param)。
- 修复: 强制使用参数化查询(PDO的
- ORM框架的误用:
- Laravel的
DB::select("select * from users where id = ?", [$id])(安全)。 - 但如果是
DB::select("select * from users where id = $id")(不安全)。 - ThinkPHP的
where('id', $id)(一般安全) vswhere('id = ' . $id)(不安全)。
- Laravel的
- 存储过程调用: 检查是否对传入参数进行了转义。
- 盲注检测: 观察
time、sleep函数是否出现在SQL查询逻辑中。
- 原生SQL写法(最危险):
跨站脚本攻击(XSS)
- 检查点:
- 输出点:
echo $_GET['name']、print_r、<?=$var?>且未使用htmlspecialchars()、htmlentities()或模板引擎转义。 - 上下文陷阱:
- HTML上下文: 使用
htmlspecialchars($var, ENT_QUOTES, 'UTF-8')。 - HTML属性上下文:
<a href="<?=$url?>">需额外处理单/双引号转义。 - JavaScript上下文:
<script>var x = '<?=$var?>';</script>极易被注入,应使用JSON编码(json_encode)。 - CSS/URL上下文: 谨慎拼接用户输入。
- HTML上下文: 使用
- 存储型XSS: 用户输入写入数据库后未转义直接显示(如评论、用户名)。
- 富文本XSS: 使用HTMLPurifier等白名单过滤器处理。
- 输出点:
文件包含漏洞(LFI/RFI)
- 检查点:
include($_GET['page'])、require_once "files/" . $user_input。- 使用
file_get_contents()、fopen()、include_once直接拼接用户路径。 - 危险函数:
include、include_once、require、require_once、file_get_contents、fopen、fread。 - 检测伪协议: 代码是否允许
php://input、php://filter、zip://、phar://等。
- 修复: 限制文件路径为白名单,或使用
realpath()规范化路径。
文件上传漏洞
- 检查点:
- 文件类型检测: 仅校验
$_FILES['file']['type'](客户端MIME,可篡改)而不对服务端getimagesize()或exif_imagetype()验证。 - 黑名单绕过: 仅拦截
.php、.php5、.phtml,但允许.pht、.php7、.shtml、.phar、.inc等。 - 上传路径: 是否允许覆盖系统文件(如
../config.php)。 - 二次渲染: 图片文件尾部隐藏PHP代码(可绕过
getimagesize())。 - WebShell检测: 检查上传后文件是否可访问。
- 文件类型检测: 仅校验
- 修复: 使用白名单扩展名、重命名文件(UUID)、将文件放在web根目录外或限制执行权限。
命令注入(OS Command Injection)
- 检查点:
exec("ping -c 4 " . $_GET['ip'])(直接拼接双引号、反引号、、、)。system()、passthru()、shell_exec()、proc_open()、popen()等函数。- PHP内部命令执行:
eval()、assert()、preg_replace('/e/')(已废弃)、create_function()、array_map()带用户回调。
- 修复: 对输入进行严格白名单校验,或使用
escapeshellarg()/escapeshellcmd()。
逻辑漏洞 & 访问控制
- 检查点:
- 权限缺失: 后台/管理页面是否允许未登录或低权限用户访问(如
admin.php未做if (isAdmin())检查)。 - IDOR(不安全的直接对象引用):
delete.php?id=123,用户可遍历ID删除他人数据(检查$user->id == $owner_id)。 - CRSF(跨站请求伪造): 关键操作(改密、转账)是否没有
Token或Referer验证。 - 会话管理:
session_id是否可预测,session是否在https下设置了Secure和HttpOnly标志。 - 密码安全: 使用
md5()或sha1()而不加salt。
- 权限缺失: 后台/管理页面是否允许未登录或低权限用户访问(如
不安全的配置
- php.ini:
display_errors = On(生产环境应关闭)。allow_url_include = On(应关闭,防止RFI)。magic_quotes_gpc = On(已废弃,不应依赖)。session.use_strict_mode = 0(应开启)。
- 框架/中间件:
debug模式在生产环境开启。.env文件未添加到.gitignore且暴露了数据库密码。log文件(如storage/logs/laravel.log)可被直接访问。
实战审计步骤
- 全局依赖审计:
- 运行
composer audit检查composer.lock中的已知漏洞。
- 运行
- 入口文件与路由审计:
- 从
index.php或框架路由文件(如routes/web.php)开始,追踪用户数据的流向。
- 从
- 敏感函数搜索:
- 使用grep或代码分析工具搜索以下危险函数(按优先级):
eval、preg_replace(带/e)、assert、create_function(命令执行)include、require、file_get_contents(文件包含)shell_exec、exec、system、passthru、popen(命令执行)mysql_query、mysqli_query、PDO::query(无预处理)unserialize(反序列化漏洞)header(未过滤回车换行注入)
- 使用grep或代码分析工具搜索以下危险函数(按优先级):
- 数据流追踪:
- 输入: 所有
$_GET、$_POST、$_COOKIE、$_FILES、$_SERVER、$_REQUEST。 - 传递: 这些变量如何经过函数处理?是否被
json_decode、base64_decode、unserialize处理? - 输出: 执行
echo、print、<?=的位置。
- 输入: 所有
- 自动化工具扫描:
- 使用 Semgrep(强烈推荐) 运行规则(如
p/php-security)。 - 用 RIPS 或 SonarQube 生成报告,然后手动验证真/假漏洞。
- 使用 Semgrep(强烈推荐) 运行规则(如
- 手动深入审查:
- 针对高风险的SQL/XSS/文件上传区域,逐行阅读逻辑。
- 检查框架自定义过滤器(如Laravel中定制的
Request规则)是否覆盖了所有场景。
最实用的工具组合
| 阶段 | 工具 | 用途 |
|---|---|---|
| 静态分析 | Semgrep | 自定义规则,精准发现模式匹配漏洞 |
| 静态分析 | PhpStorm + Intelephense | IDE实时提示、类型推断、超简化数据流追踪 |
| 已知漏洞 | composer audit | 快速检查第三方库漏洞 |
| Web扫描 | Burp Suite | 手动拦截修改请求、重放测试、SQL/XSS盲注测试 |
| 环境检测 | PHPStan (level 5+) | 检测未定义变量、类型混淆(可能导致逻辑漏洞) |
常见误区
- 依赖框架过滤器: 不要认为Laravel的
csrf或validation完全阻止了XSS,框架只过滤用户输入但不会自动对输出做HTML转义。 - 过度信任
addslashes(): 在GBK编码下,addslashes()绕过经典案例(宽字节注入)。 - 忽视
unserialize(): 反序列化漏洞在PHP中非常普遍,检查所有使用unserialize的地方。 - 忽略文件上传的二次利用: 上传一张图片后,文件名、路径信息可能被用于其他漏洞(如包含、移动、重命名)。
输出审计报告
一份标准的PHP审计报告应包含:
- 漏洞摘要: 按严重程度(Critical/High/Medium/Low)分类。
- 详细描述: 问题位置、代码片段、测试步骤(如复制Burp请求)。
- 危害分析: 此漏洞可能造成的影响(数据泄露、服务器沦陷等)。
- 修复建议: 具体代码修改方案(如替换函数名、增加过滤条件)。
对PHP代码审计,静态分析帮你快速定位可疑的“危险函数”,动态测试(抓包+手动尝试) 验证漏洞是否能被利用,而业务逻辑理解才决定该漏洞的实际危害。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播