如何加強網站的SEO - 資安篇
上一篇教各位如何將前端配合同構達成如SSR的效果,但是其實那種寫法是有一些資安隱憂需要注意的。
原本是CSR變成SSR的話,就需要考量到Server注入的資料是否有問題,因此有可能會發生XSS的問題。
SEO全系列文章
📌 如何加強網站的SEO - 基礎篇
📌 如何加強網站的SEO - 進階篇
📌 如何加強網站的SEO - SSR與CSR篇
📌 如何加強網站的SEO - 同構篇
📌 如何加強網站的SEO - 框架篇
📌 如何加強網站的SEO - 資安篇
認識Cross-Site Scripting
Cross-Site Scripting又稱為XSS,中文稱作跨網站指令碼,透過程式碼注入的方式,將程式把注入到網頁上面並且執行,而影響到網站的正常運作,XSS變化的方式不少,時常搭配HTML的斷句或是大小寫等…避開一些程式規則。
什麼狀況會發生XSS
XSS有很多案例,以下列出幾個比較重要且經典的
Reflected XSS - 即時反映的script
有任何可輸入的欄位,都必須小心發生XSS
通常惡意者會利用回吐的error,從中拿取資料1
2
3
4<form>
<input id="test" placeholder="Enter malicious input here" size="30" value="<script>alert('XSS injected!');</script>" />
<input type="submit" value="Submit" />
</form>Stored XSS - 可重複利用的script
惡意者不一定期望馬上執行這段script,可能會先把惡意程式碼透過可輸入的欄位先從到資料庫內,再到網頁call actions回撈資料後,便會執行那段惡意程式,從中取得部份資訊。
當然,儲存的XSS可能會有其他變化,例如:cookie,惡意者先把惡意程式存在cookie內,再透過網頁讀取的方式執行這段惡意程式。1
<script>alert(document.cookie)</script>
DOM XSS
正常情況下,當DOM需要被更新時,前端程式碼並不會發生任何改變。
但是當惡意者透過一些修改瀏覽網頁的話,會導致程式碼執行的邏輯被改變。
例如有一個網頁的網址如下:1
http://ex.com/main.html?default=1
惡意者可以透過修改後面的default做出一些變化,甚至可以搭配第二點的方式使用cookie。
1 | http://ex.com/main.html?default=<script>alert(document.cookie)</script> |
SPA與XSS
這裡以React為例,React能夠預先載入前端網頁,讓使用者能夠使用的更順暢。
而且React也已經實作了大部分的前端邏輯,因此開發者通常不被需要擔心會有XSS的疑慮。
例如我們開發React是以JSX進行開發,所以會先經過一段轉譯
轉譯前的JSX:
1 | const element = ( |
轉譯後的JS:
1 | const element = React.createElement( |
所以,你只要好好善用React包裝好的功能,幾乎是不用太擔心安全疑慮。
你可能需要擔心的問題:
- 使用dangerouslySetInnerHTML
- 把機敏資料送到eval()
- 使用者的href或是可注入的屬性render
在做SSR的時候,我們在做的其實就是注入script的行為,因此如果你的資料需要過濾。
下面提供幾個考量點
- 如果你的專案已經運行一段時間了,可能會有資料庫內涵XSS的隱憂,那麼建議在讀取資料的時候,就需要對資料進行過濾,再找時間把資料庫的資料進行過濾。
- 如果專案還在進行開發,那麼可以在使用者儲存資料之前,就做好防呆來避免儲存惡意程式。
如何過濾
之前的同構文章有提到從Node注入資料
1 | const injectHTML = (data, { |
我們從這段程式可以看出,meta和React的INITIAL_STATE很有可能被注入惡意資料。
因此在這邊可以加入過濾的function,判斷內文如果有<符號,就取代成其他編碼方式而不影響呈現。
1 | const filterXSS = (content) => { |
這樣就可以寫成:
1 | const injectHTML = (data, { |
等等,那麼script呢
你還在上面的例子發現了什麼嗎? 沒錯,${script}也有可能塞入其他惡意程式
但是這邊有可能是你已經預期會在前端塞入的資料,是你可控制的範圍,而非外來資料
那麼不就不用過濾了嗎?這就要看你可能塞入什麼程式了
這邊可能發生XSS的狀況會是結構化資料
1 | <script type="application/ld+json"> |
如果你直接把描述放到結構化資料裡面,不就會發生XSS或是跑版了嗎?
因此如果有需要的話,也可以在這邊去做處理