最近在學習SSTI(服務器模板注入),所以在此總結一下
0x00 Twig的介紹
什么是Twig?
Twig是一款靈活、快速、安全的PHP模板引擎。
Twig的特點?
快速:Twig將模板編譯為純粹的,最優化的PHP代碼。它的開銷與常規的PHP代碼相比,已經降到了極低。
安全:Twig擁有沙盒模式,用於評估未受信任的模板代碼。這使得Twig可以用於允許用戶自行修改模板設計的應用程序中。
靈活:Twig由一個靈活的詞法分析器和解析器驅動。這使得開發者可以自定義標簽和過濾器,並創建自己的DSL。
為何會有這款模板引擎?
在為PHP帶來模板引擎時,許多人會告訴你PHP本身就是一款模板引擎啊。雖說一開始PHP是作為一門模版語言使用,但它並不像近年來的任何模板引擎一樣發展。事實上,他不支持現代模板引擎的許多特性:
1.簡潔:PHP語言在涉及到輸出轉義時冗長而可笑。
<?php echo $var ?>
<?php echo htmlspecialchars($var, ENT_QUOTES, 'UTF-8') ?>
相比之下,Twig擁有非常簡潔的語法,它使得模版更具可讀性:
{{ var }} {{ var|escape }} {{ var|e }} {# shortcut to escape a variable #}
2.模版導向語法:Twig為通用的模式提供了快捷方式,例如在遍歷一個空數組時,會顯示一個默認文本:
{% for user in users %} * {{ user.name }} {% else %} No users have been found. {% endfor %}
3.全功能:Twig為你提供了輕松構建強大模版的一切:多重繼承,塊,自動化輸出轉義,以及其他許多特性:
{% extends "layout.html" %} {% block content %} 頁面內容... {% endblock %}
4.易學:Twig的語法非常易學,即使是網頁設計師也能毫無阻礙地快速完成工作:
當然,PHP也是許多模板引擎項目中用到的語言。但它們中的大多數仍是使用PHP 4開發的,並且不支持最佳的web開發實踐:
5.可擴展性:即使是在最復雜的情況下,Twig也足夠靈活滿足你的需求。得益於開放的體系,你可以實現你自己的語言結構(標簽、過濾器、函數、甚至運算符等)來創建你自己的DSL。
6.已被單元測試:Twig經歷過完整的單元測試,它是穩定的,能用於大型項目的。
7.文檔:Twig擁有完整的文檔,以及專用的在線手冊,當然還有完善的API文檔。
8.安全:說到安全,Twig擁有一些獨特的特性:
自動輸出轉義:為安全考慮,你可以全局啟用自動輸出轉義,或者只對某個塊啟用:
{% autoescape true %} {{ var }} {{ var|raw }} {# var won't be escaped #}
{{ var|escape }} {# var won't be doubled-escaped #}
{% endautoescape %}
9.沙盒:Twig可以在沙盒環境下評估任意模版,用戶只能訪問一組有限的標簽,過濾器,以及由開發者定義的對象方法。沙盒可以全局地或者單獨對某些模版啟用:
{{ include('page.html', sandboxed = true) }}
10.清晰的錯誤信息:無論何時你在模版中遇到了語法錯誤,Twig都會輸出帶有出錯的文件名和行號的幫助信息。它非常有助於調試。
11.快速:Twig的目標之一就是盡可能地快。為了盡可能實現最佳的速度,Twig將模版編譯成極致優化的PHP代碼。它的開銷與常規的PHP代碼相比,已經降到了極低。
0x01 安裝
需求:
和php一樣,發布大版本后,以前的版本依然會維護一段時間,因此twig目前有兩個版本都在維護
1.X版本:至少PHP 5.2.7,從1.34開始至少需要PHP 5.3.3.
2.X版本:至少PHP 7.0.0
包括drupal8在內,許多項目都還在使用1.X,這里以1.X做主要介紹,有多種方法安裝twig,官方推薦使用composer,運行如下命令即可:
composer require twig/twig:~1.0
為了提高性能twig還提供了有限功能的php層面的C擴展,詳見官網,這里我們以下載文件方式來安裝。
安裝:
到這里下載文件包:https://github.com/twigphp/Twig/tags
本文選擇: v1.35.3 解壓下載的Twig-1.35.3.tar.gz 由於twig使用psr-0的自動加載方式,所以里面的lib就是我們需要的庫文件,將其復制到網站根目錄即可
你可以在本機通過phpstudy等軟件安裝運行環境,這里以E:\phpStudy\PHPTutorial\WWW作為網站根目錄,在SSTI文件夾下創建SSTI1.php
內容如下:
1 <?php 2
3 require_once '../Twig-1.35.3/lib/Twig/Autoloader.php'; 4
5 Twig_Autoloader::register(); 6
7 $loader = new Twig_Loader_Array(array( 8
9 'index' => 'Hello {{ name }}!',
10
11 )); 12
13 $twig = new Twig_Environment($loader); 14
15 echo $twig->render('index', array('name' => 'Fabien'));
運行結果如圖:
這說明安裝完成
開始使用:
假設你已經按前一步設置好了目錄與文件,我們來從文件系統加載一個模板文件,進行顯示:
在根目錄建立子目錄“template”用以存放模板文件,在其中建立文本文件“index.html.twig”,內容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>twig</title>
</head>
<body> hello world ! {{name}} </body>
</html>
然后訪問站點http://127.0.0.1/template.php,你將會看到:
同時在站點根目錄下多出了一個子目錄:
templates_cache
其中存放着為提高性能編譯為php文件的模板文件,默認只編譯一次,如原文件發生變化需重新編譯(刪除緩存)
在以上代碼中Twig_Environment是twig的中樞對象,類接收兩個參數:
\Twig_Environment::__construct (Twig_LoaderInterface $loader = null, $options = array())
$loader是實現了\Twig_LoaderInterface接口的加載器,用於加載模板文件
$options是選項數組,控制twig行為,有效選項如下:
debug:是否處於調試模式,布爾值,默認為false
charset:模板使用的字符編碼,默認為 UTF-8
base_template_class:基礎模板類,用於被編譯后的模板php文件,默認為Twig_Template
cache:可選值有儲存編譯后模板的目錄,或者為false以禁用編譯緩存,這是默認值,也可以是緩存對象(接口:Twig_CacheInterface的實例,見開發者篇)
auto_reload:布爾值,在原模板文件改變時是否重新加載,如果沒有提供那么將根據debug選項決定
strict_variables:是否使用嚴格變量模式,默認為false,為真時模板中使用無效變量將拋出錯誤,否則為NULL
autoescape:是否全局自動轉義,可能的值有:false(禁止轉義),true(默認值,等效為html),html(轉義html實體),js(轉義js),css(轉義css),url(轉義url),html_attr(轉義html和屬性),name(基於模板擴展名設置自動轉義策略),PHP callback(由一個php回調來返回轉義策略,該回調接收模板的名字做參數)
optimizations:模板編譯時的優化選項,“-1”代表開啟全部優化(默認值),“0”代表禁用優化,還有其他值詳見下集中優化擴展一節
渲染代碼:$twig->render('index.html.twig', array('name' => 'yunke'));原型為:
render($name, array $context = array())
第一個參數是模板的文件名,用於加載模板
第二個是傳遞給模板的變量數組,鍵名為在模板中的變量名,鍵值為對應的變量值,該變量數組稱為模板的“上下文”,在模板中通過“_context”能訪問到該數組,下文將多次提到“上下文”就是指該變量數組
模板文件命名:
twig模板是一個段文本內容,可以存放在數據庫、php變量、文件等地方,如果是文本文件,命名是任意的,任意擴展名均可,但通常使用“.twig”或“.html.twig”作為擴展名
參考:https://www.poos.cn/node/65
https://www.kancloud.cn/yunye/twig-cn/159454