时间轴


演示案例
TP 框架-开发-配置架构&路由&MVC 模型
1、配置架构-导入使用
 
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
 2、路由访问-URL 访问
 
 
  
 
  
 
  
 
 非官方写法访问方式
当使用非官方的写法访问时,可以看到只能用?x=1来访问,而当使用/x/1时访问报错。



官方写法访问方式
当使用官方写法访问时,?name=12可以访问,/name/12也可以访问

<?php
namespace app\index\controller;
use think\Controller;
use think\Request;
class Index extends Controller
{
    public function index()
    {
        return '123';
    }
    public function xiaodi()
    {
        return $this->request->param('name');
    }
}
?>

MVC模型
对应model(模板) view(视图) controller(控制器)
其中核心代码文件在controller中
3、数据库操作-应用对象
连接数据库

首先在application下找到database.php文件

修改database(数据库名)为demo01,username为root,密码123456,端口号3306,其余根据自己需求修改。

查询数据库

在navicat中找到之前创建的news表格

在ThinkPHP—>application下新建一个test文件夹,并在这个文件夹下创建controller文件夹,其中包含Test.php
非官方写法
以之前的news.php为例
<?php
include 'config.php';
//读取news.html中的内容
$template=file_get_contents('news.html');
$id=$_GET['id'] ?? '1';
$sql="select * from news where id=$id";
echo $sql;
$data=mysqli_query($con,$sql);
while($row=mysqli_fetch_row($data)){
    $page_title=$row[1];
    $heading=$row[2];
    $subheading=$row[3];
    $content=$row[4];
    $item=$row[5];
}
$template=str_replace('{page_title}',$page_title,$template);
$template=str_replace('{heading}',$heading,$template);
$template=str_replace('{subheading}',$subheading,$template);
$template=str_replace('{content}',$content,$template);
$template=str_replace('{$item}',$item,$template);
eval('?>'.$template);
//eval函数会将传递给它的字符串作为PHP代码执行,即将?>连接到$template的开头,再执行该字符串
?> 当执行?id=1 and 1=1时,可以看到这个值会被接收
当输入?id=2时会出现报错

官方写法
<?php
namespace app\Test\controller;
use think\Db;
use think\Controller;
class Test extends Controller
{
    public function testsql()
    {
        //使用tp框架操作mysql数据库
        //SELECT * FROM `think_user` WHERE  `id` = 1 LIMIT 1
        //规矩写法
        $id = request()->param('x');
        $data = Db::table('news')->where('id', $id)->find();
        return json($data);
    }
}
?>当输入ip/index.php/test/test/testsql/x/1去查询这个数据库的时候,页面可以正常回显

并且可以发现,在/x/1后面输入任何东西都不会显示在页面上

结论
1.使用TP框架操作数据库时,默认是受到框架内置过滤保护的,而且方便开发。
2.原生态的数据库操作如果没有过滤就会受到SQL注入攻击。
4、文件上传操作-应用对象

首先在ThinkPHP—>public文件夹下新建一个upload.html,其中代码为
<form action="/index.php/test/test/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="image" /> <br>
    <input type="submit" value="上传" />
</form>Test.php中代码改为
<?php
namespace app\Test\controller;
use think\Db;
use think\Controller;
class Test extends Controller
{   public function testsql(){
    //使用tp框架操作mysql数据库
    //SELECT * FROM `think_user` WHERE  `id` = 1 LIMIT 1
    //规矩写法
//    $id=request()->param('x');
//      $data=Db::table('news')->where('id',$id)->find();
    //原生写法 有安全隐患
    //$id=request()->param('x');
    //$data=Db::query("select * from news where id=$id");
    $username = request()->get('username/a');
    db('admin')->insert(['username' => $username]);
    return 'Update success';
    //return json($data);
}
    public function upload(){
        // 获取表单上传文件 例如上传了001.jpg
        $file = request()->file('image');//获取表单上传文件
        // 移动到框架应用根目录/uploads/ 目录下
        $info = $file->validate(['size'=>1567800,'ext'=>'jpg,png,gif'])->move( '../uploads');
        if($info){
            // 成功上传后 获取上传信息
            // 输出 jpg
            echo $info->getExtension();
            // 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg
            echo $info->getSaveName();
            // 输出 42a79759f284b767dfcb2a0197904287.jpg
            echo $info->getFilename();
        }else{
            // 上传失败获取错误信息
            echo $file->getError();
        }
    }
}在ThinkPHP下创建uploads文件夹,用来存储接收的文件
由于phpstudy中的根目录就是public文件夹,因此可以直接用ip/upload.php来访问

当尝试上传图片时,就会跳转到以下页面

而当上传txt、docx等文件时,就会提醒文件后缀不允许

5、前端页面渲染-MVC 模型

在ThinkPHP—>application—>index下创建view文件夹,再在view下创建index文件夹,其中包含index.html和edit.html。

edit.html代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>sabiqudi</title>
</head>
<body>
kcnnqi
</body>
</html>index.html代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{$name}</title>
</head>
<body>
{$email}
</body>
</html>index.php代码如下:
<?php
namespace app\index\controller;
use think\Request;
use think\Controller;
class Index extends Controller
{   public function index(){
    //return 123;
    $this->assign('name','ThinkPHP');
    $this->assign('email','thinkphp@qq.com');
    // 或者批量赋值
    $this->assign([
        'name'  => 'ThinkPHP',
        'email' => 'thinkphp@qq.com'
    ]);
    // 模板输出
    return $this->fetch('');//更改要渲染的页面
}
}当index.php中为return $this->fetch('');时,默认渲染index.html,访问后页面如下:

当index.php中为return $this->fetch('edit');时,渲染edit.html,访问后页面如下:

TP 框架-安全-不安全写法&版本过滤绕过
1、内置代码写法
例子:不合规的代码写法-TP5-自写
 
 
   
 
   
 
   
 
   
 
   
 
   
 
  2、框架版本安全
例子 1:写法内置安全绕过-TP5-SQL 注入
参考文章:https://www.cnblogs.com/Yhck/p/15808056.html

可以看到,由于这个漏洞出现的版本是5.0.13-5.0.15,5.1.0-5.1.5,所以后续会用到5.0.14版本进行演示。下面先用5.0.22版本做一个对比。

由于5.0.22版本不在漏洞适用范围之内,可以看到页面返回为null

之后用5.0.14版本演示,先在phpstudy中更改路径为5.0.14中的public文件夹

为了看是否指向正确,可以让代码输出123来检验
<?php
namespace app\index\controller;
class Index
{
    public function index()
    {
        echo 123;
    }
}之后也是配置数据库

将index.php中的代码改为
<?php
namespace app\index\controller;
class Index
{
    public function index()
    {
        $username = request()->get('username/a');
        db('users')->where("id")->update(['username'=> $username]);
    }
}按照下面的命令访问
发现虽然报错,但是直接爆出了数据库名demo01

例子 2:内置版本安全漏洞-TP5-代码执行
 
 
   
 
  逻辑越权(类似于linux中的用户等级)
如下图,假设管理员的uid=1,普通会员的uid=100。当使用select * from users where username=‘admin’来取出uid结果时,如果uid=1,则展示管理员页面。
 
 
   
 
  






















