XSS (cross-site scripting) 是很常见的网路攻击。身为网页前端或后端工程师,在面试中,很常会问到 XSS 的问题,因为面试官要确定你对于 XSS 的基本概念需要有所掌握。
什么是 XSS?XSS 攻击是指当某个恶意用户,从客户端注入攻击脚本来达到某种目的(例如:窃取 Cookie、Session、密码等),导致其他用户受到波及。之所以会说是跨域 (cross-site),是因为这种攻击方式,通常是从可信的来源发出,因此能够绕过同源政策 (same origin policy)。举例来说,某个用户以合法身份进到某个网站,这时因为他是合法身份,网站认为该用户输入的东西是可信任的,所以当该用户注入攻击脚本时,网站也会认为该脚本是可信任的。
最常见的 XSS 攻击是把 JavaScript 的脚本注入到输入框中。例如在某个论坛网站中,恶意用户把攻击脚本注入到输入框,然后变成某篇论坛贴文。这时当其他用户进到论坛时,因为浏览了那篇带有恶意脚本的贴文,所以被攻击。
用户可以输入恶意的 Javascript 语法,让系统出现问题,有兴趣的可以透过这个网站来试试看。
因为 JavaScript 几乎可以做到任何事,所以 XSS 的攻击能做到的事情也是五花八门。举例来说,窃取别的用户的 cookie,然后透过拿到的 cookie 来发送请求;或者是窜改网页内容。下面分享一个早些年直播平台 Twitch 因为防御做得不够完善,被恶搞的例子。这个例子就是透过 XSS 达成的。
XSS 攻击的类型Stored XSS被保存在资料库中的 Javascript 引起的攻击称为 Stored XSS,最常见的就是文章、留言等,因为用户可以任意输入内容,若没有检查,则
此种手法通常都用于钓鱼、社交工程等方式诱骗用户点入连结。
DOM-Based XSSDOM 全名为 Document Object Model,它可以利用 Javascript 动态产生完整的网页,不用透过后端,因此 DOM-Based XSS 是指网页上的 Javascript 在执行过程中,没有检查输入资料,使得操作 DOM 的过程中带入了恶意代码。
DOM-Based XSS在同一个网址上,透过 DOM 的方式直接显示在前端页面
var hello = function () {
let name = document.getElementById("name").value;
document.getElementById("show").innerHTML = name;
};
Hi,
因此只要将输入的内容写为
则会因为读取不出图片而产生错误,触发 onerror ,并执行 alert(123) 。
此类型的攻击,或许没办法直接让用户输入语法,但可以搭配 Stored XSS 和 Reflected XSS 制造出内容,再藉由 Javascript 动态产生有效的 DOM 物件来执行恶意代码。
如何防御 XSS?DOM-Based 防范 - 检查输入栏位。此攻击需要从前端去防范,任何的输入栏位,例如留言栏位、档案上传栏位、表单的栏位等,都要有跳脱的机制,让脚本被转换成字符串。举例来说,如果攻击者输入 ,我们把< 转成< ,在画面上依然是呈现< 但是对程式来说,它不会被当成 HTML 标签来解析。
确保来自使用者的脚本不会被执行。透过CSP (content security policy) 来设定有哪些网域(domains ) 来的脚本该被浏览器认为是该被执行的,然后浏览器只执行那些该被执行的脚本。举例来说,如果设定只有来自与网站同一个网域的脚本可被执行,那么其他由恶意攻击者注入的脚本,就会被认定成不该执行的,就不会被执行。
Stored、Reflected 防范。这两种都必须由后端进行防范,任何允许用户输入的内容都要检查,删除相关的关键字,像是