最近在看《白帽子講Web安全》這本書政勃,對于XSS有了一定的了解∏簦現(xiàn)在對于書中關(guān)于防御XSS的4種方法做一些總結(jié)與解說鸽疾。
XSS的本質(zhì)
XSS事件發(fā)生在網(wǎng)站前端吊洼,在相關(guān)的數(shù)據(jù)替換到前端頁面中時,新舊數(shù)據(jù)結(jié)合制肮,混淆了頁面原本的語義冒窍,產(chǎn)生了新的語義。以下面這種情況為例:
<a href="$var">test</a>
將$var的值注入到頁面中弄企,本來是為了提供一個跳轉(zhuǎn)用的url地址超燃。但若將$var的值設(shè)為" onclick=alert(1)\,則以上HTML變?yōu)榱耍?/p>
<a href="" onclick=alert(1) \">test</a>
點擊test文字后拘领,會進(jìn)行alert輸出意乓,即改變了原有的HTML語義。
HtmlEncode
當(dāng)$var變量出現(xiàn)在HTML標(biāo)簽或?qū)傩灾袝r,XSS可分別通過以下兩種方法來進(jìn)行注入届良。
- 在HTML標(biāo)簽中笆凌,如下所示:
<p>$var</p>
若不對$var進(jìn)行任何處理,當(dāng)$var的值為<script>alert(1)</script>時士葫,在一些老式的瀏覽器中乞而,HTML代碼如下:
<p><script>alert(1)</script></p>
則這些瀏覽器會執(zhí)行alert的js操作,實現(xiàn)了XSS注入慢显。
- 在HTML屬性中爪模,如下所示:
<p name="$var">test</p>
若不對$var進(jìn)行任何處理,當(dāng)$var的值為"> <script>alert(1)</script>時荚藻,HTML代碼如下:
<p name=""> <script>alert(1)</script>">test</p>
則瀏覽器會執(zhí)行alert的js操作屋灌,實現(xiàn)了XSS注入。
為了防御這兩種XSS应狱,可以采用對$var變量進(jìn)行HtmlEncode的方法共郭。HtmlEncode的作用是將$var的一些字符進(jìn)行轉(zhuǎn)化,使得瀏覽器在最終輸出結(jié)果上是一樣的疾呻,但能夠防止注入的JavaScript執(zhí)行除嘹。
HtmlEncode支持的轉(zhuǎn)換舉例如下:
& --> &
< --> <
> --> >
以
<script>alert(1)</script>
為例,對$var進(jìn)行HtmlEncode后的結(jié)果為:
<script>alert(1)</script>
以上HTML在瀏覽器中的顯示結(jié)果就是<script>alert(1)</script>岸蜗,實現(xiàn)了將$var作為純文本進(jìn)行了輸出尉咕,且不引起JavaScript的執(zhí)行。
JavaScriptEncode
當(dāng)$var變量出現(xiàn)在<script>標(biāo)簽內(nèi)或其它JavaScript的執(zhí)行環(huán)境中時散吵,XSS可通過以下方法來進(jìn)行注入龙考,示例如下:
<script>
var x = "$var";
</script>
若不對$var進(jìn)行任何處理,當(dāng)$var的值為";alert(1);"時矾睦,JavaScript代碼如下:
<script>
var x = "";alert(1);""
</script>
則瀏覽器會執(zhí)行alert的js操作晦款,實現(xiàn)了XSS注入。
為了防御這種XSS枚冗,可以采用對$var變量進(jìn)行JavaScriptEncode的方法缓溅。JavaScriptEncode的作用可以是將$var中除了數(shù)字、字母外的所有字符進(jìn)行十六進(jìn)制化處理赁温,使得瀏覽器最終輸出結(jié)果上是一樣的坛怪,但能夠防止注入的JavaScript執(zhí)行。
以
";alert(1);"
為例股囊,對$var進(jìn)行JavaScriptEncode后的結(jié)果為:
\x22\x3balert\x281\x29\x3b\x22
其中\(zhòng)x28代表(袜匿,\x29代表),以上字符串在JavaScript環(huán)境中即為"alert(1)"稚疹,內(nèi)容不變居灯,但XSS并不執(zhí)行。
CSSEncode
當(dāng)$var變量出現(xiàn)在<style>標(biāo)簽內(nèi)或其它css的執(zhí)行環(huán)境中時,XSS的注入和防御原理同JavaScript怪嫌。在此不累述了义锥。
css中xss的注入,在現(xiàn)在的瀏覽器中基本已經(jīng)被禁止了岩灭,因此也比較少見拌倍。
URLEncode
當(dāng)$var變量出現(xiàn)在url跳轉(zhuǎn)地址中時,XSS可通過以下方法來進(jìn)行注入噪径,示例如下:
<a >test</a>
若不對$var進(jìn)行任何處理柱恤,當(dāng)$var的值為" onclick="alert(1);return false;"時,代碼如下:
<a onclick="alert(1);return false;">test</a>
此時就會阻止了url頁面跳轉(zhuǎn)找爱,實現(xiàn)了XSS注入膨更。
為了防御這種XSS,可以采用對$var變量進(jìn)行URLEncode的方法缴允。URLEncode的作用是將字符轉(zhuǎn)化為%HH的形式,支持的轉(zhuǎn)換舉例如下:
空格 --> %20
< --> %3c
> --> %3e
以上述的
" onclick="alert(1);return false;"
為例珍德,URLEncode后的結(jié)果如下:
%22%20onclick%3d%22alert%281%29%3breturn%20false%3b%22
原有代碼變?yōu)椋?/p>
<a >test</a>
此時便阻止了XSS的注入练般。
如果上述例子改為:
<a href="$var">test</a>
即$var指代了完整的url地址,則可能出現(xiàn)以下兩種情況:
<a href="javascript:alert(1)">test</a>
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTs8L3NjcmlwdD4=">test2</a>
這兩種代碼都能夠注入XSS锈候,為了防御這些情況薄料,可以先檢測$var中是否包含url的protocol字段,如果沒有泵琳,就加上摄职,再對整個url進(jìn)行URLEncode處理。
結(jié)語
以上是我的一些經(jīng)驗與心得获列,若有不足之處谷市,請予指正。希望這篇文章對你有所幫助_击孩。