<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: `", ', <, >`

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"}