关于XSS攻击
XSS(Cross-site scripting)通常会透过网站与使用者可进行资料互动的物件,
(如文字输入框、网址列的GET参数等)插入恶意的JavaScript程式码进行攻击,
进而窃取网站系统中的资密资料,是相当常见的网页程式资讯漏洞,
也是OWASP TOP 10与CWE Top 25统计最常见的资安弱点之一。
XSS攻击的种类
1. 储存型
让恶意的JS程式码储存在资料库中,后续的使用者若有存取到相关的资料,
就会执行到该恶意程式码。
<input id="content"></input><input id="submit" type="button" value="submit"><div id="showContent"></div>
如上述的程式码,假设showContent
是用来显示content
的内容,
并且该程式未做XSS防範,那代表user若在输入框输入<script>alert(1)</script>
,
并点选submit
时,可以成功将JS程式码存进资料库,showContent
显示内容时,就会跳出alert讯息:
2. 反射型
将恶意的JS程式码夹带在使用GET参数传递的网址中,
当后端要取用GET参数时,就会执行到该恶意程式码。
例如:在搜寻框输入关键字,若该网站搜寻功能使用GET参数传递关键字,
且未做XSS防範,那在网址列就会呈现出JS程式码,进而作执行:http://www.test.com/search?keyword=<script>alert(1)</script>
另外也可能透过社交工程的方式,
诱导使用者直接点选有问题的网址,从而窃取相关的私密资料。
和储存型不同的地方在于,反射型攻击不将资料储存进资料库中。
3. DOM型
DOM(Document Object Model)指的是将HTML以树状结构做表示的介面,
各个物件都有一个固定的HTML标籤格式
例如网页中的一张图片:
呈现图片的HTML标籤就是:<img src="~/cat.jpg" alt="可爱的猫猫">
DOM型的XSS攻击,是在JS载入网页时,直接在网页中嵌入夹带恶意程式码的DOM物件进行攻击。<img src="javascript:alert(1)">
确认网站是否有防範XSS攻击?
最常使用的方式就是在可以让使用者输入资料的地方(如新增资料中的文字输入栏位)
填上JS语法,如<script>alert(1)</script>
,
将资料送出之后,若网页呈现出alert讯息,则代表该网站并未(或没有完整)防堵XSS攻击。
初步的防範
1. 跳脱字元
在能够让使用者输入资料的地方,都要做跳脱(escape),
意即遇到特殊符号字元如<
、"
,都以跳脱字元代替:
html中常见的跳脱字元& = &< = <> = >" = "&apos = '
因为特殊符号做了跳脱,就算输入了JS语法,
也会因为特殊符号被视为纯文字,而无法成功执行。
除了自己写过滤器以外,目前大部分的语言也都有提供相应的跳脱套件可以使用,
如微软提供给ASP.NET系列使用的Microsoft Anti-XSS。
2. (ASP.NET)Request Validation
ASP.NET 4.0以后的版本,预设都会验证所有Request资料,若检测到含有危险性的值,
就会导向例外的错误画面:
若程式有部分功能需要传送含有JS语法的值,务必使用部分开放的方式,
而不是将整个网站的ValidateRequest设定为false。
另外请参考:
黑暗执行续-多想两分钟,你可以不用 validateRequest="false"
3. 设定CSP规则
Content Security Policy是一系列的规则,
可以加在伺服器回传的header,或HTML的<meta>
标籤中,
用来限制浏览器可以存取的资源,简单来说就像是一份白名单。
例如,若要完全限制所有的外部来源,写在header中的语法为:content-security-policy: default-src 'none';
更多CSP设定的範例可参考MDN:Content Security Policy (CSP)
若有设定好CSP规则的话,即便网站中有栏位没有做到字元跳脱的检核,
恶意的程式码仍然会因为不符合CSP规则而被挡下,
这样在前后端就都多了一层保障啰