本文目录导读:

我来帮你系统地介绍PHP代码审计中的权限审计方法和要点。
权限审计的核心关注点
认证与授权检查
// 错误示例:仅检查是否登录,未检查操作权限
if (isset($_SESSION['user_id'])) {
// 执行删除操作
$db->query("DELETE FROM users WHERE id = " . $_GET['id']);
}
// 正确示例:检查用户是否有权限操作
if ($_SESSION['role'] === 'admin' && isset($_SESSION['user_id'])) {
// 执行删除操作
$db->query("DELETE FROM users WHERE id = " . (int)$_GET['id']);
}
垂直权限提升(越权)
// 漏洞示例:普通用户可以执行管理员操作
if ($_POST['action'] === 'delete_user') {
// 普通用户也可以删除用户
$userId = $_POST['user_id'];
// 执行删除
}
水平权限提升(越权)
// 漏洞示例:用户可以查看其他用户的信息 $userId = $_GET['id']; $sql = "SELECT * FROM users WHERE id = $userId"; // 没有检查当前用户是否有权限查看该用户的信息
常见的权限审计模式
RBAC(基于角色的访问控制)
// 权限检查函数
function checkPermission($requiredRole) {
$userRole = $_SESSION['role'];
$roles = [
'admin' => 3,
'editor' => 2,
'user' => 1
];
if ($roles[$userRole] < $roles[$requiredRole]) {
header('HTTP/1.1 403 Forbidden');
die('权限不足');
}
}
// 使用示例
checkPermission('admin');
ACL(访问控制列表)
// ACL配置
$acl = [
'article' => [
'create' => ['admin', 'editor'],
'edit' => ['admin', 'editor'],
'delete' => ['admin'],
'view' => ['admin', 'editor', 'user']
],
'user' => [
'manage' => ['admin'],
'view' => ['admin', 'user']
]
];
// 权限检查
function checkACL($resource, $action) {
global $acl;
$userRole = $_SESSION['role'];
if (!isset($acl[$resource][$action])) {
return false;
}
return in_array($userRole, $acl[$resource][$action]);
}
审计常见漏洞点
URL直接访问
// 审计点:没有权限检查的页面
// admin/delete_user.php
$id = $_GET['id'];
$db->query("DELETE FROM users WHERE id = $id");
// 缺少权限检查!
API接口权限
// 审计点:API接口的权限验证
// api/user.php
header('Content-Type: application/json');
$action = $_GET['action'];
switch($action) {
case 'delete':
// 是否验证了用户身份?
// 是否验证了操作权限?
break;
}
文件操作权限
// 审计点:文件上传、删除、下载权限
if (isset($_FILES['file'])) {
// 普通用户是否可以上传文件到敏感目录?
$target = '/var/www/uploads/' . $_FILES['file']['name'];
move_uploaded_file($_FILES['file']['tmp_name'], $target);
}
权限审计检查清单
检查项目
- [ ] 所有敏感操作都需要权限验证
- [ ] 权限验证在业务逻辑之前
- [ ] 默认拒绝原则(Deny by Default)
- [ ] 会话管理安全
- [ ] CSRF防护
- [ ] 敏感操作日志记录
常见漏洞模式
// 1. 只检查登录,不检查权限
if (isset($_SESSION['user'])) { ... }
// 2. 权限检查在UI层而非后端
if ($_SESSION['role'] === 'admin') {
// 显示删除按钮
// 但后端未检查权限
}
// 3. 可预测的用户ID
$otherUser = $_GET['user_id'];
// 用户可以枚举其他用户
// 4. 权限缓存未刷新
// 用户权限变更后,会话中的权限未更新
自动化审计工具
RIPS(专业的PHP审计工具)
- 静态代码分析
- 检测常见漏洞模式
- 支持自定义规则
PHPStan(静态分析)
# 安装 composer require --dev phpstan/phpstan # 运行分析 vendor/bin/phpstan analyse src/ --level=max
Psalm(静态分析)
# 安装 composer require --dev vimeo/psalm # 运行 vendor/bin/psalm
实战审计示例
完整审计案例
<?php
// 需要审计的代码
class UserController {
public function deleteUser($userId) {
// 审计点1:是否有身份验证
if (!isset($_SESSION['user'])) {
return json_encode(['error' => '未登录']);
}
// 审计点2:权限检查是否足够
// 当前用户是否可以删除其他用户?
if ($_SESSION['user']['role'] !== 'admin') {
return json_encode(['error' => '权限不足']);
}
// 审计点3:是否存在SQL注入
// 使用prepare语句了吗?
$sql = "DELETE FROM users WHERE id = " . $userId; // 存在SQL注入
// 审计点4:操作日志记录了吗?
// 审计点5:CSRF Token验证了吗?
return json_encode(['success' => true]);
}
public function updateProfile() {
// 审计点6:用户只能更新自己的资料吗?
$userId = $_SESSION['user']['id'];
$newData = $_POST;
// 审计点7:是否验证了字段是否允许修改
foreach ($newData as $field => $value) {
$sql = "UPDATE users SET $field = '$value' WHERE id = $userId";
// 用户可以修改敏感字段吗?(如role字段)
}
}
}
修复建议模板
// 修复后的权限检查模板
function authorize($requiredPermission) {
// 1. 验证用户登录
if (!isset($_SESSION['user'])) {
http_response_code(401);
die(json_encode(['error' => '未授权访问']));
}
// 2. 验证权限
$user = $_SESSION['user'];
if (!hasPermission($user, $requiredPermission)) {
http_response_code(403);
die(json_encode(['error' => '权限不足']));
}
// 3. 验证CSRF Token
if (!verifyCsrfToken($_POST['csrf_token'] ?? '')) {
http_response_code(403);
die(json_encode(['error' => 'CSRF验证失败']));
}
// 4. 记录操作日志
logAccess($user['id'], $requiredPermission);
return true;
}
需要我详细讲解某个具体的漏洞类型,或者提供更多的审计示例吗?