PHP代码审计——Day2-Twig

S1gn·2024-04-02 09:43·168 次阅读

PHP代码审计——Day2-Twig

前置知识 - Twig

Twig是一个PHP模板引擎,它提供了一种更简洁和可扩展的方法来创建PHP应用程序的视图层。Twig模板引擎旨在将设计与业务逻辑分离,并为开发人员提供一种更加清晰和易于维护的方式来构建网页。

使用前提:在PHP项目中安装,然后引入Twig的自动加载文件

Copy
composer require twig/twig require_once 'vendor/autoload.php';

基本配置示例:

Copy
$loader = new \Twig\Loader\FilesystemLoader('path/to/templates'); $twig = new \Twig\Environment($loader, [ 'cache' => 'path/to/cache', 'debug' => true, ]);

使用FilesystemLoader来加载模板文件。将path/to/templates替换为你实际的模板目录。配置中的cache参数指定Twig编译后的缓存目录,debug参数设置为true可以使Twig在有错误时输出更详细的错误信息。

漏洞解析

Copy
// composer require "twig/twig" require 'vendor/autoload.php'; class Template { private $twig; // 初始化 Twig 环境并加载模板 public function __construct() { $indexTemplate = '<img ' . 'src="https://loremflickr.com/320/240">' . '<a href="{{link|escape}}">Next slide &raquo;</a>'; // Default twig setup, simulate loading // index.html file from disk $loader = new Twig\Loader\ArrayLoader([ 'index.html' => $indexTemplate ]); $this->twig = new Twig\Environment($loader); } // 从 $_GET 中获取名为 nextSlide 的参数,并通过 filter_var 函数验证为一个有效的 URL,并返回该URL public function getNexSlideUrl() { $nextSlide = $_GET['nextSlide']; return filter_var($nextSlide, FILTER_VALIDATE_URL); } // 渲染模板,将下一张幻灯片的链接作为参数传递给 Twig 模板引擎,然后输出渲染后的 HTML 内容 public function render() { echo $this->twig->render( 'index.html', ['link' => $this->getNexSlideUrl()] ); } } (new Template())->render();

考察点:xss漏洞

代码中使用了escapefilter_var两个过滤方法,但还是可以被绕过,程序使用 Twig 模板引擎定义的 escape 过滤器来过滤link,而实际上这里的 escape 过滤器,是用PHP内置函数 htmlspecialchars 来实现的

{{link|escape}}
这是twig自带的过滤器,在twig的文档中我们可以知道它是通过PHP的htmlspecialchars来实现的,他会将特殊字符转换为 HTML 实体。

htmlspecialchars函数:(PHP 4, PHP 5, PHP 7) 将特殊字符转换为 HTML 实体

Copy
定义 :string htmlspecialchars ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string$encoding = ini_get("default_charset") [, bool $double_encode = TRUE ]]] ) & (& 符号) =============== &amp; " (双引号) =============== &quot; ' (单引号) =============== &apos; < (小于号) =============== &lt; > (大于号) =============== &gt;

filter_var: (PHP 5 >= 5.2.0, PHP 7) 使用特定的过滤器过滤一个变量

Copy
定义 :mixed filter_var ( mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]] )

过滤函数,有一些常用的过滤器类型及对应的预定义变量:

  • FILTER_VALIDATE_EMAIL:验证是否为有效的电子邮件地址。
  • FILTER_VALIDATE_URL:验证是否为有效的URL。
  • FILTER_VALIDATE_IP:验证是否为有效的IP地址。
  • FILTER_SANITIZE_STRING:去除字符串中的 HTML 和 PHP 标记。
  • FILTER_SANITIZE_NUMBER_INT:去除字符串中的所有字符,除了数字和符号。

绕过方法

使用JavaScript伪协议绕过

Copy
<a href="javascript:;">这个标签中的javascript是啥意思?</a> // href 属性的值可以是任何有效文档的相对或绝对 URL,包括片段标识符和 JavaScript 代码段。 // 这里的href=”javascript:;”,其中javascript:是伪协议,它可以让我们通过一个链接来调用javascript函数。 // javascript:是表示在触发<a>默认动作时,执行一段JavaScript代码

demo测试

Copy
<?php $url = filter_var($_GET['url'], FILTER_VALIDATE_URL); var_dump($url); $url = htmlspecialchars($url); var_dump($url); echo "<a href='$url'>Next slide~~</a>"; ?>

构造payload:?url=javascript://comment%250aalert(1);

  • 这里的 // 在JavaScript中表示单行注释,所以后面的内容均为注释
  • 字符 %0a 为换行符,所以 alert 语句与注释符 // 就不在同一行,就能执行
  • 这里我们要对 % 百分号编码成 %25 ,因为程序将浏览器发来的payload:javascript://comment%250aalert(1) 先解码成: javascript://comment%0aalert(1) 存储在变量 $url 中,然后用户点击a标签链接就会触发 alert 函数。

修复建议

对于XSS漏洞,最好过滤关键词,将特殊字符进行HTML实体编码替换

参考文章

https://xz.aliyun.com/t/2457?time__1311=n4%2BxnieDqQqWwqCwx0v%2Bb%2BoitrGQkQetKz4D&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fu%2F10394%3Fpage%3D2
https://lanvnal.com/2020/02/19/rips-php-security-calendar-2017-xue-xi-ji-lu/#toc-heading-2

posted @   smile_2233  阅读(168)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示