前面我們通過(guò)該《XSS 跨站漏洞以及釣魚式攻擊》文章闡述了XSS攻擊的危險(xiǎn),在 View 層,可以解決 XSS 問(wèn)題。同時(shí)在《網(wǎng)站安全縱深防御原則的實(shí)施方法》闡述了“輸入檢查” 與“輸出編碼”這兩種方法在 XSS 防御效果上的差異。XSS 攻擊是在用戶的瀏覽器上執(zhí)行的, 其形成過(guò)程則是在服務(wù)器端頁(yè)面渲染時(shí),注入了惡意的 HTML 代碼導(dǎo)致的。從 MVC 架構(gòu)來(lái)說(shuō), 是發(fā)生在 View 層,因此使用“輸出編碼”的防御方法更加合理,這意味著需要針對(duì)不同上下 文的 XSS 攻擊場(chǎng)景,使用不同的編碼方式。?
在“跨站腳本攻擊”一文中,南昌網(wǎng)絡(luò)公司百恒網(wǎng)絡(luò)安全工程師將“輸出編碼”的防御方法總結(jié)為以下幾種:?
? ? ? ? 在 HTML 標(biāo)簽中輸出變量;?
? ? ? ? 在 HTML 屬性中輸出變量;?
? ? ? ? 在 script 標(biāo)簽中輸出變量;?
? ? ? ? 在事件中輸出變量;?
? ? ? ? 在 CSS 中輸出變量;?
? ? ? ? 在 URL 中輸出變量。?
? ? ? ?針對(duì)不同的情況,使用不同的編碼函數(shù)。那么現(xiàn)在流行的 MVC 框架是否符合這樣的設(shè)計(jì) 呢?答案是否定的。?
? ? ? ?在當(dāng)前流行的 MVC 框架中,View 層常用的技術(shù)是使用模板引擎對(duì)頁(yè)面進(jìn)行渲染,比如在 “跨站腳本攻擊”一章中所提到的 Django,就使用了 Django Templates 作為模板引擎。模板引 擎本身,可能會(huì)提供一些編碼方法,比如,在 Django Templates 中,使用 filters 中的 escape 作 為 HtmlEncode 的方法:?
? ? ? ?
Hello, {{ name|escape }}!
?? ? ? ?Django Templates 同時(shí)支持 auto-escape,這符合 Secure by Default 原則。現(xiàn)在的 Django Templates,默認(rèn)是將 auto-escape 開(kāi)啟的,所有的變量都會(huì)經(jīng)過(guò) HtmlEncode 后輸出。默認(rèn)是編 碼了 5 個(gè)字符:?
? ? ? ?< is converted to <?
? ? ? ?> is converted to > '
? ? ? ? (single quote) is converted to '?
? ? ? ?" (double quote) is converted to "
? ? ? ? & is converted to &
? ? ? ? 如果要關(guān)閉 auto-escape,則需要使用以下方法: {{ data|safe }} 或者 {% autoescape off %} Hello {{ name }} {% endautoescape %} 為了方便,很多程序員可能會(huì)選擇關(guān)閉 auto-escape。要檢查 auto-escape 是否被關(guān)閉也很簡(jiǎn) 單,搜索代碼里是否出現(xiàn)上面兩種情況即可。?
? ? ? ?但是正如前文所述,最好的 XSS 防御方案,在不同的場(chǎng)景需要使用不同的編碼函數(shù),如 果統(tǒng)一使用這 5 個(gè)字符的 HtmlEncode,則很可能會(huì)被攻擊者繞過(guò)。由此看來(lái),這種 auto-escape 的方案,看起來(lái)也變得不那么美好了。(具體 XSS 攻擊的細(xì)節(jié)在本書“跨站腳本攻擊”一章中 有深入探討)?
? ? ? ?再看看非常流行的模板引擎 Velocity,它也提供了類似的機(jī)制,但是有所不同的是,Velocity 默認(rèn)是沒(méi)有開(kāi)啟 HtmlEncode 的。?
? ? ? ?在 Velocity 中,可以通過(guò) Event Handler 來(lái)進(jìn)行 HtmlEncode。 eventhandler.referenceinsertion.class = org.apache.velocity.app.event.implement. EscapeHtmlReference eventhandler.escape.html.match = /msg.*/ 使用方法如下例,這里同時(shí)還加入了一個(gè)轉(zhuǎn)義 SQL 語(yǔ)句的 Event Handler。 ...?
import org.apache.velocity.app.event.EventCartridge;
? ? ? ? import org.apache.velocity.app.event.ReferenceInsertionEventHandler;?
? ? ? ?import org.apache.velocity.app.event.implement.EscapeHtmlReference;?
? ? ? ?import org.apache.velocity.app.event.implement.EscapeSqlReference;?
...?
public class Test { public void myTest() { ....?
/** * Make a cartridge to hold the event handlers */?
? ? ? ?EventCartridge ec = new EventCartridge();?
/* * then register and chain two escape-related handlers */
? ? ? ? ec.addEventHandler(new EscapeHtmlReference());?
? ? ? ?ec.addEventHandler(new EscapeSqlReference());?
/* * and then finally let it attach itself to the context */?
? ? ? ?ec.attachToContext( context );?
/* * now merge your template with the context as you normally * do */?
.... }?
}
? ? ? ? ? ? ? ?但 Velocity 提供的處理機(jī)制,與 Django 的 auto-escape 所提供的機(jī)制是類似的,都只進(jìn)行 了 HtmlEncode,而未細(xì)分編碼使用的具體場(chǎng)景。不過(guò)幸運(yùn)的是,在模板引擎中,可以實(shí)現(xiàn)自定 義的編碼函數(shù),應(yīng)用于不同場(chǎng)景。在 Django 中是使用自定義 filters,在 Velocity 中則可以使用 “宏”(velocimacro),比如: XML編碼輸出,將會(huì)執(zhí)行 XML Encode輸出 #SXML($xml)?
JS編碼輸出,將會(huì)執(zhí)行JavaScript Encode輸出 #SJS($js) 通過(guò)自定義的方法,使得 XSS 防御的功能得到完善;同時(shí)在模板系統(tǒng)中,搜索不安全的 變量也有了依據(jù),甚至在代碼檢測(cè)工具中,可以自動(dòng)判斷出需要使用哪一種安全的編碼方法, 這在安全開(kāi)發(fā)流程中是非常重要的。?
? ? ? ?在其他的模板引擎中,也可以依據(jù)“是否有細(xì)分場(chǎng)景使用不同的編碼方式”來(lái)判斷 XSS 的安全方案是否完整。在很多 Web 框架官方文檔中推薦的用法,就是存在缺陷的。Web 框架 的開(kāi)發(fā)者在設(shè)計(jì)安全方案時(shí),有時(shí)會(huì)缺乏來(lái)自安全專家的建議。所以開(kāi)發(fā)者在使用框架時(shí),應(yīng) 該慎重對(duì)待安全問(wèn)題,不可盲從官方指導(dǎo)文檔。?
? 本文僅限內(nèi)部技術(shù)人員學(xué)習(xí)交流,不得作于其他商業(yè)用途.希望此文對(duì)廣技人員有所幫助。原創(chuàng)文章出自:南昌網(wǎng)站建設(shè)公司-百恒網(wǎng)絡(luò)http://www.myforexfactory.net/如轉(zhuǎn)載請(qǐng)注明出處!