當前位置:
首頁 > 新聞 > 伺服器端模板注入

伺服器端模板注入

為什麼需要伺服器端模板(SST)?

首先解釋一下為什麼HTML代碼和應用程序邏輯混合在一起不好,看下面的例子你就知道了。假如你使用下面的代碼為你的用戶提供服務:

這不僅僅是靜態HTML代碼。用戶名是從cookie里獲取並且自動填寫的。這樣一來,只要你之前登錄過該網站,你就無需再次輸入。但是這有一個問題,那就是你必須通過某種形式將值插入到HTML文檔中,有兩種方法可以實現,一種是正確的,一種是有危害的。不過我們要先問一下,為什麼要這麼做。

下圖展示了解決該問題的完全錯誤的方法:

這段代碼有很多問題,作者不僅僅沒有對用戶的輸入進行處理,HTML代碼和PHP代碼複雜的混合在一起,非常難以理解。部分HTML代碼分布在多個函數中,這還不算什麼,當你嘗試修改HTML代碼中任何內容時,你才發現有多難受,比如新增css類或修改HTML標籤的順序。

上面這個例子顯然是有意寫的這麼爛的,不過可以通過格式化進行優化。然而,在大型的代碼庫中,即使代碼格式良好,也會很快變得無法管理。這就是為什麼我們需要模板。

什麼是伺服器端模板?

與上面混亂的代碼相比,伺服器端模板提供了一種更加簡單的方法來管理動態生成的HTML代碼。最大的優點就是你可以在伺服器端動態生成HTML頁面,看起來跟靜態HTML頁面一樣。現在我們來看看,當我們使用伺服器端模板時,複雜的代碼看起來如何。

這對前面的代碼做了一些優化,它依然是靜態的。為了顯示正確的信息而不是大括弧佔位符,我們需要一個替換它們的模板引擎。後端代碼可能是這樣的。

這段代碼的意思非常清楚,首先載入login.tpl模板文件,然後對與模板中名稱相同的變數賦值(大括弧里的變數),然後調用show()函數,相應的替換它們的內容並輸出HTML代碼。然而,我們在模板中增加了新的功能,這將會向用戶展示模板渲染的時間。

為什麼SST是危險的?

SST看起來並沒有什麼危害,但是你仔細研究的話,會發現它能在模板中執行本機函數,這就意味著如果攻擊者能夠向模板文件中寫入這種表達式的話,他們就能夠執行任意函數。但是這個文件不一定非要包含你的模板。這種情況下,模板引擎無論如何都會將文件轉換為字元串,以便用它們的結果代替表達式。這也是為什麼模板引擎允許你對它們進行傳遞字元串,而不用直接傳遞文件位置。

你可以將其和require()和eval()函數進行比較。require()函數會包含一個文件並執行,eval()函數不是執行文件,而是將字元串當成代碼來執行。你應該知道將未經處理的輸入傳遞給eval()函數是極其危險的。每一本優秀的編程書都會反覆的提到這一點。但是當涉及到處理模板引擎時,人們卻通常忽略了這一點。所以,有時候,你看到的代碼是下面這樣的:

這段代碼顯示,在模板中,有一處輸入是用戶可控的,這就意味著用戶可以執行模板表達式。

舉個例子,惡意的表達式可能非常簡單,比如[[system(『whoami』)]],這就會執行系統命令whoami。因此模板注入很容易導致遠程代碼執行(RCE),就像未經過處理的輸入直接傳遞為eval()函數一樣。這就是我們所說的伺服器端模板注入(SSTI)。這個例子非常明顯,而在實際中,漏洞會非常隱蔽,難以發現。比如將許多不同的組件連接在一起傳遞為模板引擎,但是忽視了其中的某些組件可能包含用戶可控的輸入。

web應用如何防禦SSTI?

·為了防止此類漏洞,你應該像使用eval()函數一樣處理字元串載入功能。儘可能載入靜態模板文件。

·注意:我們已經確定此功能類似於require()函數調用。因此,你也應該防止本地文件包含(LFI)漏洞。不要允許用戶控制此類文件或其內容的路徑。

另外,無論在何時,如果需要將動態數據傳遞給模板,不要直接在模板文件中執行,你可以使用模板引擎的內置功能來擴展表達式,實現同樣的效果。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 嘶吼RoarTalk 的精彩文章:

了解新型銀行類惡意軟體——FakeSpy
修補DoublePulsar支持攻擊Windows Embedded系統

TAG:嘶吼RoarTalk |