PHP框架学习——thinkphp
字数 2924 2025-10-27 12:13:03

ThinkPHP 8.x 框架入门与代码审计教学文档

第一部分:ThinkPHP 基础与URL访问

ThinkPHP(简称TP)是一个免费开源的、快速、简单的面向对象的轻量级PHP开发框架。

1.1 环境与入口

  • 入口文件:通常是项目根目录下的 public/index.php。所有对应用的请求都会经过这个入口文件。
  • 基础URL格式:ThinkPHP遵循MVC(模型-视图-控制器)模式,其URL访问模式为:
    http://服务器地址/入口文件/控制器/操作/参数名/参数值/...
    
    • index.php:入口文件。
    • index:模块(或应用)名,默认是 index
    • Index:控制器名,对应 application/index/controller 目录下的 Index.php 文件。
    • test:操作名,对应 Index.php 控制器类中的 test() 公共方法。

1.2 参数传递方式

文档中提到了三种常见的参数传递方式:

方式一:传统GET传参

  • 代码示例
    public function test() {
        $name = $_GET['chuan']; // 直接使用超全局数组获取参数
        return 'hello ' . $name;
    }
    
  • 访问URL
    http://127.0.0.1/xiaodi/public/index.php/index/index/test?chuan=111
  • 特点:使用标准的 ?参数名=值 格式,与框架路由无关。

方式二:ThinkPHP Pathinfo传参(推荐)

  • 代码示例
    public function test() {
        $name = input('n'); // 使用TP助手函数 input() 获取参数,更安全
        return 'hello, ' . $name;
    }
    
  • 访问URL
    http://127.0.0.1/xiaodi/public/index.php/index/index/test/n/chuan
  • 特点:参数作为URL路径的一部分,更符合RESTful风格,是TP的默认推荐方式。

方式三:使用Request对象

  • 代码示例
    public function test(Request $request) { // 依赖注入Request对象
        $name = $request->param('n'); // 通过Request对象的param方法获取
        return 'hello, ' . $name;
    }
    
  • 访问URL:与方式二相同。
  • 特点:面向对象方式,功能更强大,可以更方便地获取各种请求数据。

1.3 跨控制器访问

  • 同模块,不同控制器

    • 控制器文件:application/index/controller/Test.php
    • 访问URL:http://127.0.0.1/xiaodi/public/index.php/index/Test/xd(访问 Test 控制器下的 xd 操作)
  • 不同模块,不同控制器

    • 控制器文件:application/test/controller/Xiaodi.php
    • 访问URL:http://127.0.0.1/xiaodi/public/index.php/test/Xiaodi/xd(访问 test 模块下的 Xiaodi 控制器中的 xd 操作)

第二部分:数据库操作与安全

数据库配置通常位于 config/database.php 文件中。

2.1 三种数据库查询方式

方式一:原生SQL查询(易产生SQL注入)

  • 代码示例
    public function login_check(){
        $id = $_GET['id']; // 直接获取用户输入,极度危险
        $sql = "select * from cw_admin where id=$id"; // 直接拼接SQL语句
        $data = mysqli_query($sql); // 执行查询
        echo $data['pass'];
    }
    
  • 风险:直接将用户输入的 $id 拼接到SQL语句中,攻击者可以构造恶意参数(如 id=1 OR 1=1)进行SQL注入攻击,获取敏感数据。

方式二:ThinkPHP安全查询(使用预编译,推荐)

  • 代码示例
    public function login_check1(Request $request){
        $id = $request->param('i');
        // Db::table 方式,where('字段名', '值') 会自动使用参数绑定
        $data = Db::table('cw_admin')->where('id', $id)->find();
        echo $data['pass'];
    }
    
  • 访问URLhttp://127.0.0.1/xiaodi/public/index.php/index/Login/login_check1/i/1
  • 安全原理:TP框架底层会将这种写法转换为预编译SQL语句,将用户输入的数据当作纯数据处理,而不是可执行的SQL代码,从而有效防止SQL注入。

方式三:ThinkPHP不安全查询(字符串拼接,危险)

  • 代码示例
    public function login_check2(Request $request){
        $id = $request->param('i');
        // where("条件字符串") 方式,如果字符串中包含变量拼接,同样存在注入风险
        $data = Db::table('cw_admin')->where("id = $id")->find(); // 危险!
        echo $data['pass'];
    }
    
  • 风险:虽然使用了TP的数据库类,但由于采用了字符串内直接拼接变量 $id 的方式,其安全风险与原生SQL查询相同。这是TP代码审计中需要重点关注的危险写法。

第三部分:ThinkPHP框架代码审计要点

根据原文内容,可以总结出以下审计关键点:

3.1 SQL注入漏洞审计

  • 高危模式:在模型或Db类操作中,where() 方法内使用字符串直接拼接用户输入。
    • ->where("id = $id")
    • ->where("name LIKE '%".$name."%'")
  • 安全模式:使用参数绑定的方式。
    • ->where('id', $id)
    • ->where('name', 'like', "%$name%")(注意:Like查询需确保变量被正确转义或绑定,高版本TP已做处理,但审计时仍需留意复杂情况)

3.2 其他常见漏洞审计方向

虽然原文未深入提及,但在TP框架审计中还需关注:

  • 输入验证与过滤:检查是否使用 input() 函数的过滤功能(如 input('param.name/s') 强制转换为字符串)或 Request 对象的 filter 方法对用户输入进行过滤。
  • 命令执行:查找 exec(), system(), shell_exec() 等函数,其参数是否由用户可控。
  • 文件操作:检查文件包含(include, require)、文件上传、文件读取等操作,用户输入的参数是否被安全地过滤。
  • 模板注入:如果项目使用了TP的模板引擎,检查是否允许用户控制模板内容。

第四部分:实战案例——CMS漏洞复现思路

原文提到“cms代码审计框架小迪漏洞复现”,这是一个典型的白盒审计流程:

  1. 环境搭建:下载目标CMS(如某个基于ThinkPHP开发的系统)并配置好本地测试环境。
  2. 功能点分析:浏览CMS的前后台功能,寻找与用户交互密切的点,如:登录、搜索、订单查询、文章展示等。
  3. 代码追踪
    • 以“搜索功能”为例,在前台搜索框输入关键词并抓包,找到对应的参数(如 keywords)。
    • 根据URL路由规则(如 /index/search/index)找到对应的控制器文件(application/index/controller/Search.php)和操作方法(index())。
    • 在方法中查看 keywords 参数是如何被接收和使用的(是直接用 $_GET 还是 input()?)。
    • 追踪 keywords 变量被传递到哪个数据库查询方法中,检查查询的写法是否安全(即第二部分中的方式二 vs 方式三)。
  4. 漏洞验证:如果发现不安全的写法,构造特殊的Payload(如搜索关键词 ' AND (SELECT 1 FROM (SELECT SLEEP(5))a)-- )进行延时注入测试,验证漏洞是否存在。
  5. 总结报告:记录漏洞位置、成因、利用方式及修复建议。

总结

本教学文档从ThinkPHP框架的基础URL访问和数据库操作讲起,重点剖析了安全与不安全的编码实践,并系统性地介绍了代码审计的核心要点。关键在于:

  1. 理解框架机制:掌握TP的MVC路由和参数获取方式。
  2. 树立安全意识:明确SQL注入等漏洞的产生根源在于“不可信的用户输入”与“代码/指令”的拼接。
  3. 掌握审计模式:在审计时,像侦探一样追踪用户输入的数据流,最终判断它是否被“安全地”使用。

希望这份详尽的文档能帮助您系统地学习ThinkPHP框架及其安全审计知识。

ThinkPHP 8.x 框架入门与代码审计教学文档 第一部分:ThinkPHP 基础与URL访问 ThinkPHP(简称TP)是一个免费开源的、快速、简单的面向对象的轻量级PHP开发框架。 1.1 环境与入口 入口文件 :通常是项目根目录下的 public/index.php 。所有对应用的请求都会经过这个入口文件。 基础URL格式 :ThinkPHP遵循MVC(模型-视图-控制器)模式,其URL访问模式为: index.php :入口文件。 index :模块(或应用)名,默认是 index 。 Index :控制器名,对应 application/index/controller 目录下的 Index.php 文件。 test :操作名,对应 Index.php 控制器类中的 test() 公共方法。 1.2 参数传递方式 文档中提到了三种常见的参数传递方式: 方式一:传统GET传参 代码示例 : 访问URL : http://127.0.0.1/xiaodi/public/index.php/index/index/test?chuan=111 特点 :使用标准的 ?参数名=值 格式,与框架路由无关。 方式二:ThinkPHP Pathinfo传参(推荐) 代码示例 : 访问URL : http://127.0.0.1/xiaodi/public/index.php/index/index/test/n/chuan 特点 :参数作为URL路径的一部分,更符合RESTful风格,是TP的默认推荐方式。 方式三:使用Request对象 代码示例 : 访问URL :与方式二相同。 特点 :面向对象方式,功能更强大,可以更方便地获取各种请求数据。 1.3 跨控制器访问 同模块,不同控制器 : 控制器文件: application/index/controller/Test.php 访问URL: http://127.0.0.1/xiaodi/public/index.php/index/Test/xd (访问 Test 控制器下的 xd 操作) 不同模块,不同控制器 : 控制器文件: application/test/controller/Xiaodi.php 访问URL: http://127.0.0.1/xiaodi/public/index.php/test/Xiaodi/xd (访问 test 模块下的 Xiaodi 控制器中的 xd 操作) 第二部分:数据库操作与安全 数据库配置通常位于 config/database.php 文件中。 2.1 三种数据库查询方式 方式一:原生SQL查询(易产生SQL注入) 代码示例 : 风险 :直接将用户输入的 $id 拼接到SQL语句中,攻击者可以构造恶意参数(如 id=1 OR 1=1 )进行SQL注入攻击,获取敏感数据。 方式二:ThinkPHP安全查询(使用预编译,推荐) 代码示例 : 访问URL : http://127.0.0.1/xiaodi/public/index.php/index/Login/login_check1/i/1 安全原理 :TP框架底层会将这种写法转换为预编译SQL语句,将用户输入的数据当作纯数据处理,而不是可执行的SQL代码,从而有效防止SQL注入。 方式三:ThinkPHP不安全查询(字符串拼接,危险) 代码示例 : 风险 :虽然使用了TP的数据库类,但由于采用了字符串内直接拼接变量 $id 的方式,其安全风险与原生SQL查询相同。 这是TP代码审计中需要重点关注的危险写法。 第三部分:ThinkPHP框架代码审计要点 根据原文内容,可以总结出以下审计关键点: 3.1 SQL注入漏洞审计 高危模式 :在模型或Db类操作中, where() 方法内使用字符串直接拼接用户输入。 ->where("id = $id") ->where("name LIKE '%".$name."%'") 安全模式 :使用参数绑定的方式。 ->where('id', $id) ->where('name', 'like', "%$name%") (注意:Like查询需确保变量被正确转义或绑定,高版本TP已做处理,但审计时仍需留意复杂情况) 3.2 其他常见漏洞审计方向 虽然原文未深入提及,但在TP框架审计中还需关注: 输入验证与过滤 :检查是否使用 input() 函数的过滤功能(如 input('param.name/s') 强制转换为字符串)或 Request 对象的 filter 方法对用户输入进行过滤。 命令执行 :查找 exec() , system() , shell_exec() 等函数,其参数是否由用户可控。 文件操作 :检查文件包含( include , require )、文件上传、文件读取等操作,用户输入的参数是否被安全地过滤。 模板注入 :如果项目使用了TP的模板引擎,检查是否允许用户控制模板内容。 第四部分:实战案例——CMS漏洞复现思路 原文提到“cms代码审计框架小迪漏洞复现”,这是一个典型的白盒审计流程: 环境搭建 :下载目标CMS(如某个基于ThinkPHP开发的系统)并配置好本地测试环境。 功能点分析 :浏览CMS的前后台功能,寻找与用户交互密切的点,如:登录、搜索、订单查询、文章展示等。 代码追踪 : 以“搜索功能”为例,在前台搜索框输入关键词并抓包,找到对应的参数(如 keywords )。 根据URL路由规则(如 /index/search/index )找到对应的控制器文件( application/index/controller/Search.php )和操作方法( index() )。 在方法中查看 keywords 参数是如何被接收和使用的(是直接用 $_GET 还是 input() ?)。 追踪 keywords 变量被传递到哪个数据库查询方法中,检查查询的写法是否安全(即第二部分中的方式二 vs 方式三)。 漏洞验证 :如果发现不安全的写法,构造特殊的Payload(如搜索关键词 ' AND (SELECT 1 FROM (SELECT SLEEP(5))a)-- )进行延时注入测试,验证漏洞是否存在。 总结报告 :记录漏洞位置、成因、利用方式及修复建议。 总结 本教学文档从ThinkPHP框架的基础URL访问和数据库操作讲起,重点剖析了安全与不安全的编码实践,并系统性地介绍了代码审计的核心要点。关键在于: 理解框架机制 :掌握TP的MVC路由和参数获取方式。 树立安全意识 :明确SQL注入等漏洞的产生根源在于“不可信的用户输入”与“代码/指令”的拼接。 掌握审计模式 :在审计时,像侦探一样追踪用户输入的数据流,最终判断它是否被“安全地”使用。 希望这份详尽的文档能帮助您系统地学习ThinkPHP框架及其安全审计知识。