当前位置: 首页 > news >正文

Day26 -php开发05 -搭建个人博客三种实现:自己写前后端 套用现成模板 调用第三方模板引擎smarty 及三种方法的缺点

环境要求:小皮 +  navicat + php
前置:创建新表及其记录

在demo1库下创建新的表news,列名依次如图所示,创建一条记录。

如果插入报错:Navicat报错1366-Incorrect string value:‘xxx‘ for column ‘xx‘ at row的解决方法_navicat 1366-CSDN博客

其中图片是:写所在文件夹的路径

一、基础逻辑复现

逻辑:以主键id线索 ---> 利用mysql查找语句找库里的数据 --> 

mysqli_query()执行,mysqli_fetch_row()提取 --->然后echo各个值 -->混编一下html,将图片显示
<?php
include "config.php";$id = $_GET['id'] ?? '1';
$sql = "select * from news where id=$id ";
$data = mysqli_query($con,$sql);  // 执行mysql查询语句
while ($row=mysqli_fetch_row($data)){   // 提取mysql查询后的数据echo $row['1']."<br>"; echo $row['2']."<br>";echo $row['3']."<br>";echo $row['4']."<br>";echo "<img src='$row[5]' height='300' width='400'>.</img>.<br>";}

测试一下:

但是这样显示的太过于潦草了,就没有那种结构感和秩序感。所以引入一个技术,模板技术。

二、自己去套用模板技术

原理:将模板的值以变量形式传入传出,我们只需要进行变量的赋值即可实现内容自定义。

1、拿到一套模板

先拿一套模板过来,从网上找也可以,gpt生成也可以。

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>{page_title}</title><style>/* 一些样式 */body {font-family: Arial, sans-serif;margin: 0;padding: 0;}header {background-color: #4CAF50;color: white;text-align: center;padding: 20px;}nav {background-color: #f2f2f2;display: flex;justify-content: space-between;padding: 10px;}nav a {color: black;text-decoration: none;padding: 10px;border-radius: 5px;transition: background-color 0.3s ease;}nav a:hover {background-color: #4CAF50;color: white;}.container {max-width: 1200px;margin: 0 auto;padding: 20px;}h1 {font-size: 36px;font-weight: bold;margin-bottom: 20px;}p {font-size: 18px;line-height: 1.5;margin-bottom: 20px;}ul {margin-left: 20px;margin-bottom: 20px;}li {margin-bottom: 10px;}</style>
</head>
<body>
<header><h1>{heading}</h1>
</header>
<nav><a href="#">首页</a><a href="#">新闻</a><a href="#">留言</a><a href="#">关于</a>
</nav>
<div class="container"><h1>{subheading}</h1><p>{content}</p><img src="{$item}" width="1000" height="3000"></img></div>
</body>
</html>

 看效果:确实是变量传入传出的格式。

2、后端套用模板

方法:首先利用函数 file_get_contents()将html文件导入,并用变量去接收。

           其次利用str_replace()对html前端中的变量进行赋值

1)将前端文件导入
$template = file_get_contents('new.html');

2)后端设置好变量与数据库中的数据进行对接

因为我们刚刚是直接根据索引echo出从数据库中的数据的,但是我们需要对前端的变量(做占位符)进行替换,所以我们需要创建变量来代表实际值。

while ($row=mysqli_fetch_row($data)){   // 提取mysql查询后的数据$page_title=$row['1'];$heading=$row['2'];$subheading=$row['3'];$content=$row['4'];$item=$row['5'];}

3)给前端变量(占位符)进行后端变量(实际值)的替换
$template=str_replace('{page_title}',$page_title,$template); // 参数1:模板中的占位符 参数2:实际值 参数3:搜索范围
$template=str_replace('{heading}',$subheading,$template);
$template=str_replace('{subheading}',$subheading,$template);
$template=str_replace('{content}',$content,$template);
$template=str_replace('{$item}',$item,$template);
eval('?>' . $template); // 执行

测试看效果:

3、自己套用模板容易出现的安全问题   【rce安全问题】

服务端代码执行漏洞(Remote Code Execution, RCE)

如果在数据库内加入php代码,以phpinfo为例,<?php phpinfo() ?>

再次访问页面

原因:源码中有eval(),就会直接执行变量中的值的操作。

那么我们自己去找模板,再去修改进行调用,很容易控制不好,引发各类安全问题。所以我们可以用第三方模板引擎,以Smarty为主。

三、第三方php模板引擎smarty的调用

smarty实现:实现了前后端分离,前端不会执行php代码。比自己调用模板更安全,但是不代表绝对安全。

1、使用方法
1)将smarty对应版本文件解压并放到文件夹中

2)创建一共php文件,命名为index.php 并添加代码
<?php
// 引入 Smarty 类文件
require('smarty/libs/Smarty.class.php');
// 创建 Smarty 实例
$smarty = new Smarty;
// 设置 Smarty 相关属性
$smarty->template_dir = 'smarty/templates/';
$smarty->compile_dir = 'smarty/templates_c/';
$smarty->cache_dir = 'smarty/cache/';
$smarty->config_dir = 'smarty/configs/';
// 赋值变量到模板中
$smarty->assign('title', '欢迎使用 Smarddddty');
// 显示模板
$smarty->display('index.tpl');
?>

3)设置前端页面

创建templates文件夹,并且放入index.tpl文件

将前端代码,直接放入tpl文件

我们这里用官方例子:

<!DOCTYPE html>
<html>
<head><title>{$title}</title>
</head>
<body>
<h1>{$title}</h1>
<p>这是一个使用 Smarty 的例子。</p>
</body>
</html>

访问一下index.php看结果

2、引发的安全问题(漏洞复现) 

可能存在多种漏洞,例如模板注入、cve、沙箱逃逸等。我们这里给一共cve的漏洞复现。

1)导包 并创建写入index1.php

写入:

<?phpdefine('SMARTY_ROOT_DIR', str_replace('\\', '/', __DIR__));define('SMARTY_COMPILE_DIR', SMARTY_ROOT_DIR.'/smarty3/templates_c');define('SMARTY_CACHE_DIR', SMARTY_ROOT_DIR.'/smarty3/cache');include_once(SMARTY_ROOT_DIR . '/smarty3/libs/Smarty.class.php');class testSmarty extends Smarty_Resource_Custom
{protected function fetch($name, &$source, &$mtime){$template = "CVE-2017-1000480 smarty PHP code injection";$source = $template;$mtime = time();}
}$smarty = new Smarty();
$smarty->setCacheDir(SMARTY_CACHE_DIR);
$smarty->setCompileDir(SMARTY_COMPILE_DIR);
$smarty->registerResource('test', new testSmarty);
$smarty->display('test:'.@$_GET['x']);
?>

2)进行cve复现

由于我们给了一个get参数去承接

于是我们访问时候给参数x赋值

那么就赋值给x

/index1.php?x=*/phpinfo();//

假如我们换做刚刚的4版本(演示如何使用的时候的版本),我们会发现刚刚3版本的cve漏洞不存在了。

所以这个给我们的提醒是什么??

漏洞对应版本漏洞!

第三方的插件(ueditor)、模板(smarty)、组件(shiro、fastjson)也是有漏洞的,只要符合网上提交漏洞的版本,就存在漏洞。

http://www.xdnf.cn/news/179929.html

相关文章:

  • nextjs整合快速整合市面上各种AI进行prompt连调测试
  • Java学习手册:开发 Web 网站要知道的知识
  • 马哥教育Linux云计算运维课程
  • GIS开发笔记(16)解决基于osg和osgearth三维地图上添加placeNode图标点击不易拾取的问题
  • 火语言RPA--企业微信群通知
  • vue3 内置组件KeepAlive的使用
  • Spark Streaming核心编程总结(四)
  • QtDesigner中的Spacers弹簧/间隔器
  • 一主多从+自组网络,无线模拟量信号传输专治布线PTSD
  • C语言(3)—分支和循环
  • WinForm真入门(18)——DateTimePicker‌控件解析
  • 13.组合模式:思考与解读
  • MCP实战-本地MCP Server + Client实战
  • 创建一个开机自启的服务
  • 题海拾贝:P2858 [USACO06FEB] Treats for the Cows G/S
  • 大模型图像编辑那家强?
  • 多模态常见面试题
  • 新魔百和CM311-5_CH/YST/ZG代工_GK6323V100C_2+8G蓝牙版_强刷卡刷固件包(可救砖)
  • SpringMVC 前后端数据交互 中文乱码
  • 【深度剖析】贵州茅台的数字化转型(2025)(上篇)
  • 第7章 内部类与异常类
  • 【蓝桥杯省赛真题57】Scratch穿越病毒区 蓝桥杯scratch图形化编程 中小学生蓝桥杯省赛真题讲解
  • Vue.js 核心特性解析:响应式原理与组合式API实践
  • 论文检索相关网站
  • ‌RISC-V架构的低功耗MCU多电压域优化设计
  • final static 中是什么final static联合使用呢
  • 【算法刷题】
  • MySQL 8.0 忘记登录密码 mysqld --init-file重置
  • AG32 MCU系列三合一芯片,MCU+ 2K cpld + 64Mbit PSRAM,一颗芯片同时满足多种需求。
  • 清华团队提出时序聚类数据库内高效方案,已被SIGMOD 2025接收