基于yii框架的系统审计
字数 1830 2025-08-06 08:34:57

YII框架安全审计与漏洞挖掘实战指南

1. YII框架基础

1.1 控制器基础

在YII框架中,控制器是MVC架构的核心组件之一:

  • 网页应用控制器:继承自yii\web\Controller或其子类
  • 控制台应用控制器:继承自yii\console\Controller或其子类

示例控制器定义

namespace app\controllers;
use yii\web\Controller;

class SiteController extends Controller {}

1.2 控制器ID规范

控制器ID需遵循特定命名规则:

  • 允许字符:英文小写字母、数字、下划线、中横杠和正斜杠
  • 有效示例:article, post-comment
  • 无效示例:article?, PostComment, admin\post

1.3 控制器类命名规则

控制器类名生成规则:

  1. 将正斜杠分隔的每个单词首字母大写(仅最后一个正斜杠后的部分)
  2. 去掉中横杠,正斜杠替换为反斜杠
  3. 添加Controller后缀
  4. 前面添加控制器命名空间

命名示例(假设命名空间为app\controllers):

  • articleapp\controllers\ArticleController
  • post-commentapp\controllers\PostCommentController
  • admin/post-commentapp\controllers\admin\PostCommentController

2. 路由系统分析

2.1 标准路由格式

  • 基本格式ControllerID/ActionID
  • 模块下控制器ModuleID/ControllerID/ActionID

示例:http://hostname/index.php?r=site/index 执行site控制器的index操作

2.2 自定义路由实现

审计案例中发现了自定义路由实现,关键代码如下:

public function runAction($route, $params = []) {
    $route = ltrim($route, '/');
    $pattern = '/^plugin\/.*/';
    preg_match($pattern, $route, $matches);
    
    if ($matches) {
        // 处理插件路由逻辑
        $originRouteArray = mb_split('/', $route);
        $pluginId = $originRouteArray[1] ?? null;
        
        // 构建控制器类名
        $controllerClass = "app\\plugins\\{$pluginId}\\controllers\\IndexController";
        
        // 创建控制器实例并运行动作
        $controller = \Yii::createObject($controllerClass, [$controllerId, $this]);
        return $controller->runAction($actionId, $params);
    }
    
    return parent::runAction($route, $params);
}

路由解析示例
index.php?r=plugin/booking/api/index/index
web/app/plugins/booking/controllers/api/IndexController.php::actionIndex()

3. 高效审计方法论

3.1 自动化审计流程

  1. 收集所有控制器文件

    • Linux/Mac: tree -f -i | grep "Controller.php" > url.txt
    • Windows: tree /f /a | findstr /i "Controller.php" > url.txt
  2. Python脚本自动化分析

import os
import re

def getFileNamePath(path):
    # 递归查找所有Controller.php文件
    pass

def getUri():
    # 提取action方法并构建完整URL
    pattern = r"public function action(\w+)"
    # 处理路径和构建完整路由
    pass

3.2 路由特征分析

关键特征:

  1. URL路径与文件系统路径对应关系
  2. 控制器文件名需转换为小写
  3. 多单词组合使用"-"连接
  4. 方法名去除"action"前缀

示例转换
/web/app/Api/Controllers/v1/UserController.php::actionGetUser()
index.php?r=admin/api/v1/user/get-user

4. 漏洞挖掘实战

4.1 SQL注入漏洞案例

漏洞位置BookingController.php中的actionStoreList方法

漏洞成因

  1. 直接拼接SQL查询中的longitudelatitude参数
  2. 未对用户输入进行充分过滤

关键代码

$store = BookingStore::find()
    ->select([
        '*', 
        "(st_distance(point(longitude, latitude), point($this->longitude, $this->latitude)) * 111195) as distance"
    ])
    ->keyword($this->keyword, ['like', 's.name', $this->keyword])
    ->all();

安全对比

  • select()中的参数直接拼接 → 存在SQL注入
  • andWhere()使用参数绑定 → 安全

4.2 漏洞利用方法

  1. 验证漏洞存在

    • 测试单引号:longitude=1' → 观察是否报错
  2. 构造注入payload

    longitude=1&latitude=1) OR 1=1 --
    
  3. 利用报错注入

    longitude=1' AND (SELECT 1 FROM(SELECT COUNT(*),CONCAT((SELECT version()),0x3a,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a) AND '1'='1
    

5. 防御措施

5.1 安全编码实践

  1. 始终使用参数化查询

    ->select(new Expression("st_distance(point(longitude, latitude), point(:lon, :lat)) * 111195 as distance", [
        ':lon' => $this->longitude,
        ':lat' => $this->latitude
    ]))
    
  2. 严格输入验证

    public function rules() {
        return [
            [['longitude', 'latitude'], 'number'],
            [['longitude', 'latitude'], 'match', 'pattern' => '/^[\d\.]+$/']
        ];
    }
    

5.2 框架安全配置

  1. 启用YII的安全组件
  2. 配置CSRF保护
  3. 实现RBAC权限控制
  4. 日志记录所有敏感操作

6. 审计检查清单

  1. [ ] 检查所有直接拼接SQL的地方
  2. [ ] 验证所有用户输入是否经过适当过滤
  3. [ ] 检查路由配置是否存在未授权访问
  4. [ ] 确认敏感操作是否有权限控制
  5. [ ] 检查文件上传功能的安全性
  6. [ ] 验证XSS防护措施是否到位

通过系统化的审计方法和工具辅助,可以高效发现YII框架应用中的安全漏洞,特别是当面对大型代码库时,自动化工具和脚本能显著提高审计效率。

YII框架安全审计与漏洞挖掘实战指南 1. YII框架基础 1.1 控制器基础 在YII框架中,控制器是MVC架构的核心组件之一: 网页应用控制器 :继承自 yii\web\Controller 或其子类 控制台应用控制器 :继承自 yii\console\Controller 或其子类 示例控制器定义 : 1.2 控制器ID规范 控制器ID需遵循特定命名规则: 允许字符:英文小写字母、数字、下划线、中横杠和正斜杠 有效示例: article , post-comment 无效示例: article? , PostComment , admin\post 1.3 控制器类命名规则 控制器类名生成规则: 将正斜杠分隔的每个单词首字母大写(仅最后一个正斜杠后的部分) 去掉中横杠,正斜杠替换为反斜杠 添加 Controller 后缀 前面添加控制器命名空间 命名示例 (假设命名空间为 app\controllers ): article → app\controllers\ArticleController post-comment → app\controllers\PostCommentController admin/post-comment → app\controllers\admin\PostCommentController 2. 路由系统分析 2.1 标准路由格式 基本格式 : ControllerID/ActionID 模块下控制器 : ModuleID/ControllerID/ActionID 示例: http://hostname/index.php?r=site/index 执行 site 控制器的 index 操作 2.2 自定义路由实现 审计案例中发现了自定义路由实现,关键代码如下: 路由解析示例 : index.php?r=plugin/booking/api/index/index → web/app/plugins/booking/controllers/api/IndexController.php::actionIndex() 3. 高效审计方法论 3.1 自动化审计流程 收集所有控制器文件 : Linux/Mac: tree -f -i | grep "Controller.php" > url.txt Windows: tree /f /a | findstr /i "Controller.php" > url.txt Python脚本自动化分析 : 3.2 路由特征分析 关键特征: URL路径与文件系统路径对应关系 控制器文件名需转换为小写 多单词组合使用"-"连接 方法名去除"action"前缀 示例转换 : /web/app/Api/Controllers/v1/UserController.php::actionGetUser() → index.php?r=admin/api/v1/user/get-user 4. 漏洞挖掘实战 4.1 SQL注入漏洞案例 漏洞位置 : BookingController.php 中的 actionStoreList 方法 漏洞成因 : 直接拼接SQL查询中的 longitude 和 latitude 参数 未对用户输入进行充分过滤 关键代码 : 安全对比 : select() 中的参数直接拼接 → 存在SQL注入 andWhere() 使用参数绑定 → 安全 4.2 漏洞利用方法 验证漏洞存在 : 测试单引号: longitude=1' → 观察是否报错 构造注入payload : 利用报错注入 : 5. 防御措施 5.1 安全编码实践 始终使用参数化查询 : 严格输入验证 : 5.2 框架安全配置 启用YII的安全组件 配置CSRF保护 实现RBAC权限控制 日志记录所有敏感操作 6. 审计检查清单 [ ] 检查所有直接拼接SQL的地方 [ ] 验证所有用户输入是否经过适当过滤 [ ] 检查路由配置是否存在未授权访问 [ ] 确认敏感操作是否有权限控制 [ ] 检查文件上传功能的安全性 [ ] 验证XSS防护措施是否到位 通过系统化的审计方法和工具辅助,可以高效发现YII框架应用中的安全漏洞,特别是当面对大型代码库时,自动化工具和脚本能显著提高审计效率。