#Front-end

前言

談到 XSS(Cross-site scripting),許多人可能都只想到「就是網站上被攻擊者植入程式碼」,但若是仔細去想的話,會發現這之中其實還有很多環節都可以再深入探討。

而我所謂的這些「環節」,也可以理解成不同的「關卡」。

舉例來說,第一關當然就是盡可能防止自己的網站被 XSS 攻擊,不要讓攻擊者在網站中能夠植入程式碼。而「讓攻擊者在網站中植入程式碼」這件事,又可以往下再細分成不同地方的植入,例如說 HTML 的植入,或者是 HTML 元素屬性中的植入,又或是 JavaScript 程式碼中的植入,這些都有著不同的攻擊以及防禦方式。

而除了防止被植入程式碼以外,防守方應該還要進一步去想:「那如果真的不幸被植入程式碼了,可以怎麼辦?」

這就是第二個關卡。雖然說第一關我們已經盡可能做好準備了,但難保不會有漏洞產生,因此守好第一關是不夠的,也要對第二關進行防守。

假設今天攻擊者真的找到一個地方植入程式碼,那我們是不是可以想辦法阻止它執行?這就是 CSP(Content Security Policy)出場的時候了,藉由設定一些規則讓不合法的程式碼無法執行。例如說可以讓 inline 的 JavaScript 無法執行,那 <img src=x onerror=alert(1)> 就會變得無效。

若是攻擊者真的很厲害,連 CSP 的規則都繞過了呢?這時就進入到第三關了,第三關的假設是攻擊者已經能夠在網站上執行任意程式碼。

這時候還可以防守什麼呢?那就是試圖把損害控制到最低。

以 Medium 這種部落格的平台來說,若是可以利用 XSS 把別人的帳號奪走(account takevoer),就是個嚴重的漏洞;或是因為 Medium 有付費牆的功能,因此若是能透過 XSS 把錢轉到攻擊者的帳號,也會是一個很嚴重的問題。

而我們要在「網站已經被 XSS」的前提下,試圖去防禦這些攻擊。

接著,就讓我們來看看不同的關卡有哪些不同的防禦方法。

閱讀更多

前言

之前在公司內接到了一個需求,需要產生出一份 PDF 格式的報告。想要產一份 PDF 有很多種做法,例如說可以先用 Word 做,做完之後再轉成 PDF。但我聽到這需求時,最先出現的想法就是寫成網頁,然後再利用列印功能轉成 PDF。

我在前公司的時候看過一個用 JS 來產生 PDF 的專案,是用 PDFKit 來做,自由度極高,但我覺得滿難維護的。原因是用這一套的話,就有點像是把 PDF 畫出來,你要指定 (x,y) 座標去畫東西,可能改一個小地方,就要改很多行程式碼。

那時候我想說怎麼不直接用最簡單的 HTML + CSS 就好,切好版之後再轉成 PDF,如果不想手動轉,也可以透過 headless chrome 去轉,因為是網頁的關係所以應該滿好維護的。而且排版的話因為是用 HTML 跟 CSS,應該會比用畫的簡單許多才對。

直到我後來接觸到網頁轉 PDF,才發現事情不像我想的這麼簡單。

閱讀更多

前言

Intigriti 是國外的一個 bug bounty 平台,每個月都會推出一個 XSS 挑戰,有大約一到兩週的時間可以去思考,目標是在特定網站上面執行 alert(document.domain),解出來之後把結果透過 Intigriti 平台回報,最後會隨機抽 3 個解掉的人得到他們自己商店的優惠券。

上個月的挑戰因為解出來的人不多,所以我有幸運抽到 50 歐元的優惠券,其實很划算,因為商店賣的東西其實都滿便宜的,我買了一件 t-shirt + 兩頂帽子再加國際運費,大概 45 歐元左右。

不過這種獎品就是靠運氣啦,還是解題好玩比較重要。

挑戰網址在這邊:https://challenge-0521.intigriti.io/

閱讀更多

前言

有天我在網路上閒晃的時候,看到了一個 XSS challenge:Intigriti’s 0421 XSS challenge - by @terjanq,除了這個挑戰本身很吸引我之外,更吸引我的是出題的作者。

之前在網路上找到的許多比較偏前端的資安相關資源,都是由這個作者在維護或是貢獻的,例如說 Tiny XSS Payloads 或者是令人大開眼界的 XS-Leaks Wiki

Intigriti 這個網站似乎每個月都會舉辦這種 XSS challenge,而這一次的是他們有史以來舉辦過最難的一個。挑戰時間從 4/19~4/25,有一週的時間可以嘗試,最後成功解出的有 15 人。三月份的挑戰有 45 人解開,二月份有 33 人,所以這一次解出的人數確實少了許多,可想而知題目的難度。

我大概花了五天的時間,每天卡關的時候都想說「放棄好了,坐等解答」,但卻又時不時會有一些新的想法出現,想說就繼續試一下,最後終於在截止的那一天於時限前解開,解開的時候雙手握拳然後手肘往後,大喊:「太神辣」。

這篇想來記錄一下解題的心得,之前有寫了英文版的但大概比小學生作文還不如,還是寫個中文版的比較能完整表達自己的想法。標題會有個「上」是因為這篇寫我的解法,下一篇想來寫作者的解法,下下篇分析其他人的解法。

但我的部落格似乎被下了還沒寫好的系列文都會斷連載的詛咒,希望這次可以撐過去。

閱讀更多

前言

如果你不知道什麼是 XSS(Cross-site Scripting),簡單來說就是駭客可以在你的網站上面執行 JavaScript 的程式碼。既然可以執行,那就有可能可以把使用者的 token 偷走,假造使用者的身份登入,就算偷不走 token,也可以竄改頁面內容,或是把使用者導到釣魚網站等等。

要防止 XSS,就必須阻止駭客在網站上面執行程式碼,而防禦的方式有很多,例如說可以透過 CSP(Content-Security-Policy)這個 HTTP response header 防止 inline script 的執行或是限制可以載入 script 的 domain,也可以用 Trusted Types 防止一些潛在的攻擊以及指定規則,或是使用一些過濾 XSS 的 library,例如說 DOMPurify 以及 js-xss

但是用了這些就能沒事了嗎?是也不是。

如果使用正確那當然沒有問題,但若是有用可是設定錯誤的話,還是有可能存在 XSS 的漏洞。

前陣子我剛從公司內轉到一個做資安的團隊 Cymetrics,在對一些網站做研究的時候發現了一個現成的案例,因此這篇就以這個現成的案例來說明怎樣叫做錯誤的設定,而這個設定又會帶來什麼樣的影響。

閱讀更多

前言

CSS 寫一陣子之後,大家對於常見的屬性應該都很熟了,例如說最基本的 display、position、padding、margin、border、background 等等,在寫 CSS 的時候不需要特別查什麼東西,很順的就可以寫出來。

這些屬性之所以常見,是因為許多地方都用得到所以常見,而有些 CSS 屬性只能使用在某些特定地方,或者是只有某個特定的情境之下才會出現。我很常會忘記這些沒那麼常用到的屬性,但在某些時候這些屬性其實特別重要。

因此這篇想來介紹一些我覺得不太好記但是卻很好用的 CSS 屬性,也是順便幫自己留個筆記。

閱讀更多

前言

只要是開發 JavaScript 相關的專案,我的起手式通常都是 ESLint + Prettier,如果你沒有聽過這兩套的話我稍微講一下,Prettier 是幫你格式化程式碼用的,用了之後不必再跟其他人爭論到底要不要加分號,if 區塊的 { 要不要換行,一行最多到底能幾個字。只要用 Prettier,就是讓它幫你全權決定(雖然也有設定檔可以調整就是了)。

這其實對團隊滿有幫助的,因為程式碼格式可以統一,要空幾格也可以統一,在基本的 coding style 上面會長差不多。而 ESLint 雖然也有些跟格式相關的部分,但更多的是寫程式時候的一些 best practice,例如說使用變數前要先宣告、不會更改的變數用 const 之類的,這已經脫離了格式的範圍。

所以 ESLint 搭配 Prettier,就可以讓整個 codebase 的品質有最低限度的保障,至少不會出現排版很慘烈的狀況。而使用 ESLint 時最多人搭配的規則應該就是 Airbnb JavaScript Style Guide,裡面有每一條規則的詳細解釋。

之前在寫 code 時我突然想到一個地方好像很適合用 ESLint,就嘗試了看看,發現要做一個「堪用」的 plugin 比想像中簡單一些,就以這篇文章記錄一下過程跟心得。

閱讀更多

前言

這篇技術含量比較少一點,來跟大家分享一下寫這系列文的過程以及寫完之後的一些感想。

如果你還沒看這系列文的話,傳送門如下:

閱讀更多

前言

在前面幾篇裡面,我們知道 CORS protocol 基本上就是為了安全性所產生的協定,而除了 CORS 以外,其實還有一系列跟跨來源有關的東西,例如說:

  1. CORB(Cross-Origin Read Blocking)
  2. CORP(Cross-Origin Resource Policy)
  3. COEP(Cross-Origin-Embedder-Policy)
  4. COOP(Cross-Origin-Opener-Policy)

是不是光看到這一系列很類似的名詞就已經頭昏眼花了?對,我也是。在整理這些資料的過程中,發現跨來源相關的安全性問題比我想像中還來得複雜,不過花點時間整理之後發現還是有脈絡可循,因此這篇會以我覺得應該比較好理解的脈絡,去講解為什麼會有這些東西出現。

除了上面這些 COXX 的各種東西,還有其他我想提的跨來源相關安全性問題,也會在這篇一併提到。

在繼續下去之前先提醒一下大家,這篇在講的是「跨來源的安全性問題」,而不單單只是「CORS 的安全性問題」。CORS protocol 所保護的東西跟內容在之前都介紹過了,這篇要談的其實已經有點偏離大標題「CORS」完全手冊,因為這跟 CORS 協定關係不大,而是把層次再往上拉高,談談「跨來源」這件事情。

所以在看底下的東西的時候,不要把它跟 CORS 搞混了。除了待會要講的第一個東西,其他的跟 CORS 關係都不大。

閱讀更多

前言

在上一篇裡面我們提到了常見的 CORS 錯誤解法,以及大多數狀況下應該要選擇的解法:「請後端加上 response header」。

但其實「跨來源請求」這個東西又可以再細分成兩種,簡單請求跟非簡單請求,簡單請求的話可以透過上一篇的解法來解,但非簡單請求的話就比較複雜一些了。

除此之外,跨來源請求預設是不會把 cookie 帶上去的,需要在使用 xhr 或是 fetch 的時候多加一個設定,而後端也需要加一個額外的 header 才行。

與 CORS 相關的 header 其實不少,有些你可能聽都沒聽過。原本這篇我想要把這些東西一一列出來講解,但仔細想了一下覺得這樣有點太無趣,而且大家應該看過就忘記了。

那怎樣的方法會比較好呢?大家都喜歡聽故事,因此這篇讓我們從故事的角度下手,為大家講述一段愛與 CORS 的故事。

主角的名字大家都知道了,對,就是毫無新意的小明。

閱讀更多