框架ThinkPHP(小迪网络安全笔记~

免责声明:本文章仅用于交流学习,因文章内容而产生的任何违法&未授权行为,与文章作者无关!!!
附:完整笔记目录~
ps:本人小白,笔记均在个人理解基础上整理,若有错误欢迎指正!

1.5 🐘框架&ThinkPHP

  1. 引子:本章主要介绍ThinkPHP(PHP开发框架)的简单使用和一些安全问题。

  2. 什么是ThinkPHP
    ThinkPHP是一个免费开源的,快速、简单的面向对象的轻量级PHP开发框架,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。本文使用ThinkPHP版本为v5.0.14 & v5.0.22。(emmm,这俩版本官方好像都下不到了,直接用小迪提供的)(→ -_- 写到最后发现v5.0.22好像没用上。。。)
    这里附一张ThinkPHP的logo:
    logo

    (注:若想完整了解ThinkPHP,可参考其v5.0的官方手册,https://doc.thinkphp.cn/v5_0/default.html

  3. ThinkPHP的简单使用

    1. 首先先认识一下ThinkPHP的目录结构(删减了一部分,仅对本文所用到的目录进行展示)

      project  应用部署目录
      ├─application           应用目录(可设置)
      │  ├─common             公共模块目录(可更改)
      │  ├─index              模块目录(可更改)
      │  │  ├─controller      控制器目录
      │  │  ├─view            视图目录
      │  │  └─ ...
      │  ├─config.php         应用(公共)配置文件
      │  ├─database.php       数据库配置文件
      │  └─ ...
      ├─extend                扩展类库目录(可定义)
      ├─public                WEB 部署目录(对外访问目录)
      │  ├─index.php          应用入口文件
      │  └─ ...
      ├─runtime               应用的运行时目录(可写,可设置)
      ├─vendor                第三方类库目录(Composer)
      ├─thinkphp              框架系统目录
      │  ├─tpl                系统模板目录
      │  ├─base.php           基础定义文件
      │  └─ ...
      ├─build.php             自动生成定义文件(参考)
      ├─think                 命令行入口文件
      ├─ ...
      
    2. 架构配置(入口文件&数据库配置&调试开关)

      1. 入口文件
        什么是ThinkPHP的入口文件呢?我们来看一下官方手册上的解释:用户请求的PHP文件,负责处理一个请求(注意,不一定是URL请求)的生命周期,最常见的入口文件就是 index.php。简单来说,就是在一个ThinkPHP项目中接收并处理用户发起请求的文件。
        v5.0默认入口文件位于 public/index.php ,我们将public目录设置为网站根目录并进行访问:
        image-20250212105037959
      2. 数据库配置文件
        数据库的配置文件往往位于应用目录或者模块目录下面的 database.php 。我们查看一下位于 /application/database.php 的数据库配置文件内容:
        image-20250212110031947
      3. 调试开关
        ThinkPHP项目的调试开关位于 /application/config.php 文件中,同样的,我们来看一下:
        image-20250212110636146
        当开启调试模式后,我们再次访问该项目,也就是访问 /public/index.php 文件:
        image-20250212111156795
      4. 版本信息
        这里再补充一个能查看当前ThinkPHP版本信息的文件,文件位置位于 /thinkphp/base.php 。
        image-20250212111926323
    3. URL访问
      由官方手册可知,TP项目的URL访问规则共有两种
      其一为:http://serverName/index.php(或者其它应用入口文件)/模块/控制器/操作/[参数名/参数值...]
      另一为:http://serverName/index.php(或者其它应用入口文件)?s=/模块/控制器/操作/[参数名/参数值...]
      需要注意的是,使用url访问TP项目时,默认是不区分大小写的,也就是说其中的 /模块/控制器/操作 均会被自动转换为小写。接下来分别对模块目录,控制器目录以及操作文件做一介绍。
      由官方手册可知,TP项目中所有的模块目录均位于 /application 下,即 /模块 指的就是 /application下的模块目录。而各个模块目录下又存在 /controller 控制器目录,在 /controller 控制器目录下又存在控制器类文件,其中 /控制器 指的是控制器类文件中的控制器类,/操作 指的是该类下所定义的方法。
      我们可以先看一看TP默认的控制器类文件是什么?image-20250212141918706
      使用上文所介绍的url规则,尝试访问该控制器类文件中的操作:
      image-20250212142045541
      至于为什么即使不使用该url也能访问到TP的默认页面,可以看 /application 目录下的 config.php 配置文件。
      image-20250212142635546

    4. 变量获取
      由ThinkPHP官方手册可知,可通过Request对象完成全局输入变量的检测、获取和安全过滤,支持包括$_GET$_POST$_REQUEST$_SERVER$_SESSION$_COOKIE$_ENV等系统变量,以及文件上传信息。也就是说在使用TP开发的系统中,有一种遵从框架规则的新的全局变量获取方式。
      接下来,通过简单的demo来认识一下TP中的变量获取方式:

      // 首先新建一个test模块,并在该模块下创建Test控制器类
      // 编写操作代码
      class Test{public function vartest(){// 获取请求参数值的原生方法/*$x1 = $_GET['x1'];return '接收到的get参数值为:'.$x1;*/// http://192.168.2.106:82/index.php/test/Test/vartest?x1=1999er// 接收到的get参数值为:1999er// 由Request对象获取请求参数值/*$x2 = Request::instance()->param('x2');return '接收到的get参数值为:'.$x2;*/// http://192.168.2.106:82/index.php/test/Test/vartest/x2/sjjjer// 接收到的get参数值为:sjjjer// 补:PARAM是框架提供的能自动识别与接收不同请求方法(get、post、put)参数值的变量// 由助手函数获取参数值$x3 = input('param.x3');return '通过助手函数接收到的get参数值为:'.$x3;// http://192.168.2.106:82/index.php/test/Test/vartest/x3/sjjjer// 通过助手函数接收到的get参数值为:sjjjer}
      }
      
    5. 数据库操作
      ThinkPHP内置了抽象数据库访问层,把不同的数据库操作封装起来,我们只需要使用公共的Db类进行操作。

      1. Db类运行原生SQL语句

        class Test
        {public function datatest(){// Db类运行原生SQL语句,支持query查询,execute写入操作$res1 = Db::query('select * from tptest where id = ?',[input('param.id')]);dump($res1);// http://192.168.2.106:82/index.php/test/Test/datatest?id=2/*array(1) {[0] => array(6) {["id"] => int(2)["name"] => string(6) "李四"["age"] => int(35)["position"] => string(12) "产品经理"["email"] => string(16) "lisi@example.com"["created_at"] => string(19) "2025-02-11 10:37:32"}}*/$res2 = Db::execute('insert into tptest (id,name,age) values (?,?,?)',[5,input('param.name'),input('param.age')]);dump(Db::query('select name,age from tptest where id = ?',[5]));// http://192.168.2.106:82/index.php/test/Test/datatest?name=SJ&age=19/*array(1) {[0] => array(2) {["name"] => string(2) "SJ"["age"] => int(19)}}*/}
        }
        
      2. Db类构造SQL语句

        class Test
        {public function datatest1(){// Db类构造SQL语句$res1 = Db::table('tptest')->where('id = ?',[input('param.id')])->find();// 等价于 select * from tptest where id = '所接收的数据'dump($res1);// 使用助手函数构造SQL语句$res2 = db('tptest')->where('id = ?',[input('param.id1')])->find();dump($res2);// http://192.168.2.106:82/index.php/test/Test/datatest1?id=2&id1=5// 结果同上}
        }
        
    6. 模板引擎调用
      在TP框架中,内置模板引擎包含PHP原生模板和Think模板引擎,默认使用Think模板引擎(/application/config.php文件内可查看)。同样,通过简单的demo来调用一下:

      <!DOCTYPE html>
      <html lang="zh">
      <!-- 等待调用的模板示例 -->
      <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>{$name}</title>
      </head>
      <body><p>{$text}</p>
      </body>
      </html>
      
      use think\Controller;class Test extends Controller
      {public function temtest(){// 调用模板// 模板变量赋值$this->assign(['name' => 'temtest','text' => 'Hello ^_^~']);// 模板输出return $this->fetch('index');}
      }
      

      模板文件往往位于模块下的view目录中,尝试访问该操作,http://192.168.2.106:82/index.php/test/Test/temtest ,页面输出如下:
      image-20250213195409824

    了解到这些,就简单具备了TP框架的使用能力。接下来,再通过简单的demo来了解下TP框架可能产生的安全问题。

  4. TP框架写法&版本安全

    1. 写法安全
      以SQL注入为例,我们在TP v5.0.14中写一段可能会产生SQL注入的不安全代码。
      写法一:

      class Sqldemo
      {public function demo1(){// 未按照框架要求而使用原生写法执行sql$con = mysqli_connect("localhost", "root", "123456", "phpdemo", "3306");$id = input('param.id');$sql = "select * from tptest where id = $id";$result = mysqli_query($con, $sql);$rows = [];if ($result) {while ($row = mysqli_fetch_assoc($result)) {$rows[] = $row;}}dump($rows);}
      }
      

      测试注入语句,http://192.168.2.106:82/index.php/test/Sqldemo/demo1?id=-1%20union%20select%201,2,user(),database(),5,6 ,可以看到,该写法导致SQL注入成功。
      image-20250213214248148

      写法二:

      class Sqldemo
      {public function demo2(){// 使用Db类运行原生sql// 方法一:// $sql = Db::query("select * from tptest where id = ?",[input('param.id')]);// 方法二:$id = input('param.id');$sql = Db::query("select * from tptest where id = $id");dump($sql);}
      }
      

      当采用写法二时,且使用同样的注入语句,可以发现方法一无法注入而方法二则注入成功。我们可以看一下当采用不同方法时TP所执行的SQL语句分别是什么。(需要打开调试开关)
      方法一:select * from tptest where id = '-1 union select 1,2,user(),database(),5,6'
      方法二:select * from tptest where id = -1 union select 1,2,user(),database(),5,6
      可以很明显的看到,法一将用户所传递的参数预编译为了字符串,再传递给SQL语句,从而杜绝了SQL注入。而法二则仅是将用户所传递参数拼接到了SQL语句中,因此即使法二看着与法一相差不大,但却能成功被SQL注入。

      写法三:

      class Sqldemo
      {public function demo3(){// 使用Db类构造sql语句$id = input('param.id');$sql = Db::table('tptest')->where('id', $id)->select();dump($sql);}
      }
      

      当采用写法三时,此时无论注入语句如何输入,如/index.php/test/Sqldemo/demo3?id=-1%20union%20select%201,2,user(),database(),5,6 ,其最终执行的SQL语句都会被转换为 SELECT * FROM `tptest` WHERE `id` = -1,很安全,可以说几乎彻底杜绝了SQL注入。
      难道说在TP框架中采用Db类构造SQL已经无懈可击了吗,并非如此绝对,只不过确实更安全更难以突破,对安全从业者的要求也更高。若对突破这些开源框架感兴趣,可参考一些大佬分析TP的文章,如https://github.com/Mochazz/ThinkPHP-Vuln

    2. 版本安全
      哈哈,终于可以抛开上面那些烦人的代码了,到了我这种脚本小子最喜欢的环节了。本文所说版本安全,实质上是指若目标采用了TP框架,且符合漏洞版本,就可以直接上工具一把梭了。(工具选择狐狸工具箱的thinkphp检测工具)
      image-20250213232825883

    至此,本章内容结束!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/19832.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sql数据执行失败,三个命令依次执行

set global innodb_strict_mode off set global.sql_mode ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION; set sql_mode ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION;

【网络安全】零基础入门网络安全劝退指北

作为从16年接触网络安全的小白&#xff0c;谈谈零基础如何入门网络安全&#xff0c;有不对的地方&#xff0c;请多多指教。 这些年最后悔的事情莫过于没有把自己学习的东西积累下来形成一个知识体系。 如何入门 简单了解网络安全 网络安全就是指的确保网络系统中的数据不被别…

【Linux】网络基础

目录 一、协议分层 &#xff08;一&#xff09;计算机网络 &#xff08;二&#xff09;协议分层 &#xff08;三&#xff09;OSI模型 &#xff08;四&#xff09;TCP/IP协议 二、网络传输过程 三、IP地址和MAC地址 &#xff08;一&#xff09;IP地址 &#xff08;二&a…

ms-swift3 序列分类训练

目录 引言 一、数据集准备 二、训练/推理代码 2.1 训练 2.2 推理 三、性能验证 引言 swift 3.x支持了序列分类Command Line Parameters — swift 3.2.0.dev0 documentation 想尝试一下用多模态&#xff08;图像&#xff09;的序列分类与普通的图像分类任务有啥区别 一、…

STC 51单片机63——关于STC8H的ADC通道切换问题

使用STC8H时&#xff0c;发现在ADC中断中只能使用一个通道&#xff0c;即使切换了通道&#xff0c;那么数据要不为0&#xff0c;要不就是原先通道的电压。查阅手册&#xff0c;内容并不多&#xff0c;没有发现专门提到的问题。只能去试试&#xff0c;最后发现在ADC中断中&#…

大数据处理如何入门

大数据处理的入门可以从以下几个方面入手&#xff1a; 1. 基础知识学习 在深入大数据领域之前&#xff0c;建议先掌握一些基础知识&#xff0c;包括数据类型、存储与处理的基本概念&#xff0c;以及常用的数据处理工具。例如&#xff0c;Python或Java编程语言在大数据领域应用…

Logistic Regression 逻辑回归中的sigmoid函数是什么?

Sigmoid函数是一种在数学、计算机科学,尤其是在机器学习和深度学习领域广泛应用的函数,以下是关于它的详细介绍: 定义与公式 Sigmoid函数的数学表达式为: S ( x ) = 1 1 + e − x S(x)=\frac{1}{1 + e^{-x}} S(x)=1+e−x1​,其中 x x x 可以是一个实数、向量或矩阵。当 …

什么是Spring Boot?

Spring Boot 是基于 Spring 框架的扩展工具&#xff0c;旨在简化 Spring 应用的初始搭建和开发流程。它通过约定优于配置和自动装配机制&#xff0c;减少了传统 Spring 开发中的繁琐配置&#xff0c;使开发者能快速构建独立运行、生产级别的应用。 Spring Boot 的核心特性 自动…

后端生成二维码,前端请求接口生成二维码并展示,且多个参数后边的参数没有正常传输问题处理

一、后端代码 1、controller GetMapping("/generateQRCode/{url}")ApiOperation(value "生成url链接二维码",notes "生成url链接二维码")public JsonResult<NewsQRCodeVo> generateQRCode(PathVariable String url,HttpServletRespons…

计算机网络(3)TCP格式/连接

1、TCP三大特点&#xff1a;面向连接、可靠、基于字节流 2、如何唯一确定一个TCP连接&#xff1f;TCP四元组&#xff1a;源地址、源端口、目的地址、目的端口 源地址和目标地址的字段(32 位)是在 IP 头部中&#xff0c;作用是通过 IP 协议发送报文给对方主机源端口和目标端口…

Visual Studio Code使用ai大模型编成

1、在Visual Studio Code搜索安装roo code 2、去https://openrouter.ai/settings/keys官网申请个免费的配置使用

Flowith.io 初探:DeepSeek-R1免费用,用画布式 AI 提升效率和创意

摘要 介绍了 Flowith.io&#xff0c;一款创新的画布式 AI 平台&#xff0c;旨在提升效率和创意。它通过独特的画布交互、Oracle AI 系统、知识花园和丰富的模型选择&#xff0c;为用户提供全新的 AI 体验。画布交互打破线性思维&#xff0c;Oracle AI 帮助任务拆解与执行&#…

JavaEE-SpringBoot快速入门

文章目录 本节目标Maven什么是Maven创建一个Maven项目maven项目功能maven的依赖管理全球仓库, 私服, 本地服务器, 配置国内镜像 第一个SpringBoot项目创建项目运行SpringBoot程序 SpringBoot原理初步Web服务器 总结 本节目标 了解什么是maven, 配置国内源使用Springboot创建项…

Win11配置wsl、ubuntu、docker

系统要求 安装WSL。 开通虚拟化&#xff1a; 准备工作 dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestartdism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestartwsl --set-default-versi…

数据结构 day02

3. 线性表 3.1. 顺序表 3.1.3. 顺序表编程实现 操作&#xff1a;增删改查 .h 文件 #ifndef __SEQLIST_H__ #define __SEQLIST_H__ #define N 10 typedef struct seqlist {int data[N];int last; //代表数组中最后一个有效元素的下标 } seqlist_t;//1.创建一个空的顺序表 seq…

C# 两种方案实现调用 DeepSeek API

目录 序 开发运行环境 访问API的一个通用方法 原生官网实现 申请 API key 调用实现 调用示例 腾讯云知识引擎原子调用 申请 API key 调用示例 小结 序 DeepSeek&#xff08;深度求索&#xff09; 最近可谓火爆的一塌糊涂&#xff0c;具体的介绍这里不再赘述&#x…

23. AI-大语言模型

文章目录 前言一、LLM1. 简介2. 工作原理和结构3. 应用场景4. 最新研究进展5. 比较 二、Transformer架构1. 简介2. 基本原理和结构3. 应用场景4. 最新进展 三、开源1. 开源概念2. 开源模式3. 模型权重 四、再谈DeepSeek 前言 AI‌ 一、LLM LLM&#xff08;Large Language Mod…

web前端第三次作业:登录窗口拖动效果

<!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>登录窗口拖动效果</title> <style>…

【PCIe 总线及设备入门学习专栏 1.1 -- PCI 设备访问方法】

文章目录 CPU 地址空间与PCI 地址空间PCI 地址空间CPU 地址空间Host Bridge PCI 设备连接框图PCI 硬件信号Configuration Commands CPU 地址空间与PCI 地址空间 PCI 地址空间 PCI总线具有32位数据/地址复用总线&#xff0c;所以其存储地址空间为2的32次方4GB。也就是PCI上的所…

CentOS 7超详细安装教程(含镜像)

1. 安装前准备 1.1 CentOS简介 CentOS&#xff08;Community Enterprise Operating System&#xff0c;中文意思是&#xff1a;社区企业操作系统&#xff09;是一种基于 Red Hat Enterprise Linux&#xff08;RHEL&#xff09;源代码构建的免费开源操作系统。它在稳定性、安全…