<img src="https://i.imgur.com/UFpn3cE.png" style="border: none; background: none; box-shadow: none;"> ## TW Tech Sharing: ## XSS in JavaScript Consumer Experience Yu-Hsien Yeh Note: ###### tags: `資訊安全` # TW Tech Sharing: XSS in JavaScript 大家好 我是葉昱賢 我是在 Consumer Experience 的裡面的前端 Team 我今天要報告的主題也是和前端開發息息相關的 XSS --- ## Outline - What is XSS? - What can XSS be used for? - XSS Attack Consequences - Types of XSS - How to prevent XSS Note: 今天主要的流程依序會是 - 介紹什麼是 XSS - XSS 能被用來做什麼事 - 被 XSS 攻擊的後果 - XSS 的類型 以及 - 如何預防 XSS 最後兩個部分會有小小的 demo 展示 讓大家看到實際上攻擊是什麼樣子 --- ## What is XSS? - The acronym of **Cross-Site Scripting** - If your website has a XSS vulnerability, which means **hackers can execute a malicious script on your website**, (A malicious script also called a **payload**) Note: 什麼是 XSS 呢? 如果是前後端的朋友應該不陌生。 XSS 是 Cross-Site Scripting 的簡稱,他本來是要叫做 CSS 的啦,但是因為他和我們大家都熟知的 CSS 階層式樣式表撞名了,所以就把第一個 Cross 換成 X,就變成 XSS 了 簡單來說,假如你的網站有 XSS 漏洞,表示駭客就可以透過這個漏洞在你的網站上面執行 JavaScript 程式 --- ## What can XSS be used for? > Nearly Everything! - Perform any action within the application that the user can perform - View any information that the user can view - Modify any information that the user can modify Note: 能夠讓駭客執行 JavaScript 程式會怎麼樣?幾乎是所有事情了 能夠做的事情太多了 基本上如果被 XSS 攻擊,你在這個網站內看得到的、做得到的 駭客也都看得到、做得到 他甚至還可以修改網站內容以及冒用你的帳號 接下來我來實際舉一些被 XSS 攻擊之後的後果 --- ## XSS Attack Consequences - Hijack the user’s session cookie and take over the account - Redirect the user to some other page or site - Modify a press release or news item could affect a company’s stock price Note: 相信大家多多少少應該都有聽過或是自己遇到過帳號被盜的經驗吧, 駭客可以藉由 XSS 偷到你的 session cookie 之後就有機會可以盜用你的帳號 如果是盜用臉書帳號,就有可能在你的塗鴉牆發了一則什麼某某商店 IPhone 出清 6 折優惠之類的詐騙訊息 再來是轉址,你有可能被轉到本身就有風險的網站,或是做得很像某個銀行登入頁面的釣魚網站, 沒有資安相關知識的人很容易就會輸入帳號密碼後被盜走存款 最後 XSS 也可以更改網站內容 在上市公司發布捏造內容的新聞稿,公司經營困難決定減資 導致股票下跌 更改電腦公司的 3C 產品或是航空公司機票的售價 甚至是在醫院的網站更改藥品服用劑量,導致受騙民眾服藥過多,威脅生命安全 --- ## Types of XSS There are 3 types of XSS: - Server side render: - Stored XSS - Reflected XSS - Client side render: - DOM-based XSS Note: XSS 分成三種 Stored XSS 儲存型 Reflected XSS 反射型 還有 DOM-based XSS DOM 型 儲存型和反射型都是後端渲染的,所以是後端工程師需要處理 DOM 型則是前端渲染,所以是前端工程師需要處理 其實以定義來說 今天的 demo 都會是 DOM-based 的 XSS 因為都是前端渲染的 但是我會做一個 setTimeout 的延遲 讓他看起來比較像是有打請求的樣子 ## 按下 :arrow_down_small: ---- ### Stored XSS <span class="fragment"> (Persistent XSS)</span> - The payload is **stored** permanently on the target server and database, such as: - forum post - guestbook comment area - **Most damaging**. If victim views the affected webpage, payload might be **executed instantly** Note: 儲存型 XSS 顧名思義會儲存在伺服器端的資料庫。 常見在論壇貼文或是訪客留言板,可以讓使用者自由輸入的地方 相較於其他種類,儲存型 XSS 的殺傷力是最強的。 因為如果不刪除或是改善這個漏洞的話,只要這個網站有使用者進來,看到這個頁面就會受到攻擊 又因為他永久儲存的特性,所以他有另外一個名稱叫做 Persistent XSS ---- ### Demo Note: 這個是我做的一個簡單的留言板 下面這個區域會把使用者的輸入顯示出來 我這邊是使用用 React 的 `dangerouslySetInnerHTML` 來渲染元素 大家有機會可以在 jukwaa 搜尋一下這個詞 滿多地方有用到的 有點出乎我意料之外 大家今天聽完就可以檢查一下有用到的地方安不安全 我們來試試看這些惡意的 payload 會顯示什麼好了 ###### 1 我們來看看這個 這個 a 可以看作是 anchor 的簡稱 可以當作是連結的意思 href 則是點擊後會轉址到的目的地 原本是預期是純文字的地方居然出現了一個連結 點下去就會導到 google 當然駭客不會這麼 peace 應該是會導到一些惡意網站之類的 ###### 2 第二個也是一個連結 href 其實不只可以放網址 他也可以執行函式 這邊為各位展示一下他也可以執行 alert 通常連結的內容都會使用聳動的標題 誘使使用者去點擊 像是什麼 breaking news 之類的 所以大家以後看到越聳動的連結 不論是在臉書還是 LINE 上面 越聳動就越需要小心注意 ###### 3 第三個就沒有這麼友善了 我們來看看內容 他是一個 image 一張圖片 但是 src 這邊是一個 x 一般來說這個 src 是要放圖片的來源 而且是要用雙引號夾起來的 像是上面的 href 那樣 但是這邊這樣輸入就是故意要觸發後面的 onerror 這個屬性 onerror 也是可以執行程式 我們來看看他執行了什麼 (點擊) 喔他拿到了密碼 這個默默在右上角上面密碼 我相信有用瀏覽器存密碼的人應該很多 而且滿多網站有做 autocomplete 的 就是你進到頁面 他如果在這個 domain name 有存密碼的話 他會這樣子自動幫你填進去 但是這樣反而給駭客有機會可以取得你的密碼 ###### 4 第四個 src 是正確的格式 所以 onerror 不會觸發反而是用 onload 顧名思義表示在 loading 的時候就會觸發這個函式 我們來試試看(點擊) 圖片馬上顯示之後就轉址了 大家應該有注意到 第三個和第四個 payload 不需要使用者點擊就會轉址和執行 payload 這個就是為什麼儲存型 XSS 危害最大的地方 今天我留 payload 在這裡 下一個訪客不需要點擊什麼連結 一進來 就會受到攻擊 完全不讓你有機會反應就被攻擊了 那儲存型 XSS 的 demo 大概就到這裡 我們回到投影片 <!-- 這個 demo 是用 React 的 `dangerouslySetInnerHTML` 來渲染元素,然後 HTML 5 有規定說用 `innerHTML` 插入的 `<script>` 不應該執行 現在的前端工程師應該都是使用三大框架來開發網站 這些主流的框架其實都有幫你做了一些基礎資安上面的防範 但是如果是舊的系統就不是用這些還算是新的框架 當然也就更容易被駭客入侵 --> ---- ### Reflected XSS - **Most common**, appear in lots of phishing e-mail - Hackers will take advantage of vulnerable website, and let them **reflect** payload to victim's browser Note: 接下來我們來介紹一下反射型 XSS。 駭客會利用一個有漏洞的網站,讓 payload 反射到使用者的瀏覽器上面執行 這個網站不一定是駭客本人架設的,只要他有 XSS 漏洞就有可能被駭客利用 接下來我們來看一下攻擊的步驟 ---- ### Reflected XSS <span class="fragment" data-fragment-index="5"> (Non-Persistent XSS)</span> <div style="position: relative;height: 600px;"> <img src="https://i.imgur.com/fbt2Th8.png" style="border: none; z-index: 1; position: absolute; left: 0;"> <img class="fragment" data-fragment-index="1" src="https://i.imgur.com/sEkXbL2.png" style="border: none; z-index: 2; position: absolute; left: 0;"> <img class="fragment" data-fragment-index="2" src="https://i.imgur.com/1NLcl7A.png" style="border: none; z-index: 3; position: absolute; left: 0;"> <img class="fragment" data-fragment-index="3" src="https://i.imgur.com/U08D84k.png" style="border: none; z-index: 4; position: absolute; left: 0;"> <img class="fragment" data-fragment-index="4" src="https://i.imgur.com/bCN96ew.png" style="border: none; z-index: 5; position: absolute; left: 0;"> </div> Note: ###### 1 駭客會先發送一個釣魚郵件或是訊息給使用者,誘使使用者去點擊他 如果是郵件就可以用按鈕或是連結包裝惡意連結 如果像是訊息可以用編碼或是縮網址來包裝,避免讓使用者發現 ###### 2 只要使用者不小心點開他使用者就會發一個帶有 payload 的 request 到有漏洞的網站 ###### 3 漏洞網站反射 payload 到使用者的瀏覽器 ###### 4 使用者的瀏覽器執行 payload ###### 5 看 payload 的內容是什麼,會傳送使用者的資料像是 cookie 或是登入的密碼給駭客 ###### 標題的 Fragment 反射型和儲存型的不同在於: 反射型的 payload 是沒有儲存在伺服器端 而是在惡意連結內 也就是說,直接拜訪這個有漏洞的網站是不會受到攻擊的 使用者要點擊釣魚連結才會觸發攻擊 因為不是永久儲存在網站,所以反射型又叫做 Non-Persistent XSS Q:為什麼要反射?直接讓使用者導到駭客自己架設的網站不是很好嗎? A:有可能駭客沒有自己架設網站,或是他是後端但是剛好有個漏洞網站讓他可以發動反射型攻擊?原因可能有很多 導到自己架設網站當然可以,可以架一個釣魚網站讓使用者自己輸入帳號密碼 或是架一個本來就已經有儲存型 XSS 的網站讓使用者腳一踏進去就讓瀏覽器夾帶 session cookie 打 request 但是那可能就不是屬於這個反射型的攻擊方法了 如果還是覺得有點抽象的話我們來看一下 demo ---- ### Demo Note: 我做了一個看起來很像 Netflix 重設密碼的釣魚信件 如果不知情的人點開了會發生什麼呢? (點擊) 你的 cookie 就被駭客拿走了 拿到 session cookie 的駭客就有機會可以盜取你的帳號 這個是怎麼做到的呢? 我們來看一下他發生了什麼事 大家可以發現我們被導到一個不安全的搜尋引擎 這個搜尋引擎其實是可以正常使用的 (輸入 cat dog taco) 你看他可以正常地顯示搜尋結果 接下來我們來看看他是怎麼搜尋的 大家可以看到網址上面有一個叫做 search 的 query string 我們如果搜尋 dog 他會把 search 改成 dog 並且顯示搜尋結果之外 也會把 search 的內容渲染在網頁上 就是這一步!這其實就跟剛剛的儲存型一樣 也是直接渲染使用者的輸入 我們來看看這個連結裡面寫了什麼 style src="" onload="javascript:alert(document.cookie)" 跟剛剛一樣是用一個 onload 的方法來執行 JavaScript 其實這個網站並不是惡意網站 但是因為他有漏洞被駭客發現並且利用 導致他變成了一個跳板 一個可以讓瀏覽器可以任意執行腳本的跳板 反射型 XSS 的概念就是如此 不用自己架設網站就可以攻擊 如果今天這個網站還有一定的公信力 那攻擊會更容易成功 假設是 google 好了 大家就算有警覺會看連結上面的 domain name 結果發現是 google.com 應該也不會有什麼戒心就點了吧 所以對於一些你很熟悉 但是可能比較冷門的網站就要留意一下 --- ## How to prevent XSS There are 3 stages to prevent XSS Note: 接下來要介紹怎麼預防 XSS 攻擊 總共分成三個階段 ## 按下 :arrow_down_small: ---- ### Stage 1: Prevent hacker inserting malicious scripts > Never trust the input from users! - Escape dangerous characters: `", ', <, >` ![](https://i.imgur.com/5pnaNdf.png) Note: 第一步就是防止 payload 被輸入 有個名言是 **永遠不要相信使用者的輸入!**,因為你不會知道在螢幕前面打字的人是不是駭客 對於使用者的輸入,一定都要做驗證,不論前端還是後端,檢查有沒有可能會是惡意內容 最入門的方法,我們可以把一些特殊符號做跳脫 常見的是 雙引號 單引號 小於 大於 等等 用來撰寫 html tag 的常用符號 ---- - Use HTML sanitize libraries likes: `DOMPurify`, `js-xss` ```javascript= import DOMPurify from 'dompurify'; var clean = DOMPurify.sanitize(dirty); ``` ```javascript= var xss = require("xss"); var html = xss('<script>alert("xss");</script>'); ``` Note: 當然這種過濾的 library 一定有人已經寫好了 關於後端我不太熟悉 如果前端的話可以使用 DOMPurify 或是 js-xss 之類的套件去過濾 把不合法的標籤或是屬性過濾掉 用法其實很簡單 只要把 payload 丟進去他就會回傳乾淨的字串資料 ---- ### Stage 2: Prevent browser executing the malicious scripts - Content Security Policy (CSP) can **prevent browser from executing unknown source code** - Can be added at server side and client side Note: 如果第一關被突破了怎麼辦? 我們還有第二關 第二關就是要防止瀏覽器執行惡意程式 我們可以在我們網站的 meta 標籤加上 CSP ,全名 Content Security Policy 的一些規則來阻止來路不明的 JavaScript 執行 (demo) 在後端和前端都可以加上這個規則 ---- - Server side can add CSP at response header: ```javascript= Content-Security-Policy: script-src 'self' trusted.com *.trusted.com ``` - You can also add CSP at your `<meta>` tag into your website's `<head>` tag ```jsx= <meta http-equiv="Content-Security-Policy" content="script-src 'self';" > ``` Note: 後端是加在 response header, 前端則是在 head 標籤裡面的 meta 標籤 他的規則真的有很多,以投影片上面的例子來說 `script-src 'self' trusted.com *.trusted.com` script-src 的意思就是可以執行 JavaScript 後面接的數值就是指 哪些地方這個 policy 可以通過 self 的意思是指接受同個來源 也就是同個 domain name 的 JavaScript 假設我今天是在 houzz 上面開發寫了這個 `script-src 'self'` 就表示我只會執行 www.houzz.com 來源的 JavaScript 就會安全很多 後面就可以放你信任的網站 domain name 像是很多網站應該也都有使用 google analytics 來分析網站的流量都是從哪裡來 那這邊可能就有需要引入 Google 分析的程式碼 你這邊的 trusted.com 就可以填 google-analytics.com 就相對不用擔心會有被攻擊的風險 說相對是因為如果今天 Google 分析也是有可能被駭客入侵 ---- ### Stage 3: Reduce the damage of XSS Attack - `HttpOnly` flag of cookie - `HttpOnly` flag will **restrict the cookie accessibility from JavaScript** - Server side can add `HttpOnly` into the `Set-Cookie` response header ``` Set-Cookie: ...; HttpOnly ``` - Client side can add it manually at browser - Two-Factor Authentication Note: 如果很不幸的前兩關都被突破了的話,我們還有最後一關第三關 不過這邊的第三關比較像是補救措施 我們可以在 cookies 上面加上一個 HttpOnly 的 flag 如果有這個 flag 我們的 cookie 便不會和 JavaScript 共享 所以就算駭客執行了 document.cookie 也拿不到東西 HttpOnly 的 flag 通常是後端回傳 response 的時候會加在 response header 裡面 不過前端在瀏覽器也可以自已決定設定哪些 cookie 需要立這個 flag (demo) 第二個方法大家一定都知道,就是二階段驗證 如果駭客拿到了你的 session cookie 想要更改你的密碼 但是如果不知道你舊的密碼他也無法更改密碼 如果今天反過來,駭客拿到了你的帳號密碼 但是他要在別的裝置登入時 如果你帳號有綁手機簡訊的二階段登入 如果沒有拿到你的手機 沒有認證碼 他也是無法登入你的帳號的 ---- ### Demo Note: 可以看到我加上 CSP 之後 head 最下面多了一個 meta 內容就是我剛剛有提到的 script-src 'self' 可以看到第一個和第二個 link 不會被擋住 因為他沒有執行 JavaScript 當然就不會被擋住 連結要用第一種方法 跳脫這些 小於大於和引號之類的特殊符號 --- <img src="https://i.imgur.com/UFpn3cE.png" style="border: none; background: none; box-shadow: none;"> ## Thank you for your time
{"metaMigratedAt":"2023-06-16T13:23:05.334Z","metaMigratedFrom":"YAML","title":"TW Tech Sharing: XSS in JavaScript","breaks":true,"slideOptions":"{\"transition\":\"slide\",\"parallaxBackgroundImage\":\"https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg\",\"parallaxBackgroundSize\":\"1905px 1080px\"}","contributors":"[{\"id\":\"e4d3b4f6-95fe-4b32-bc90-2644007583fb\",\"add\":16756,\"del\":6673}]","description":"Consumer ExperienceYu-Hsien Yeh"}
    640 views