XSS 跨網站指令碼注意事項(Cross-site scripting)

這篇要說明的是「資安」的問題

用 JavaScript 操控 HTML 的方法:

🎃 .innerHTML

🍋 方法:組完字串後,傳進語法進行渲染

  • 字串“全部組好”後,丟進瀏覽器,讓瀏覽器一次解析出各個「節點」–> 速度、效能快

🍋 優點:效能快

🍋 缺點:資安風險,要確保資料來源沒問題

🎃 .createElement

🍋 方法:以「新增 DOM 節點」來處理

  • 每做一個動作(新增元素、增加文字內容、增加 className),都必須使用 JavaScript 語法來「動態增加」

–> 因此,就需要多寫很多行程式碼(尤其是在跑for迴圈時,要多跑很多行程式碼)–> 效能差

🍋 優點:安全性高

🍋 缺點:效能差

.innerHTML資安問題

html:

1
2
3
<textarea name="" id="content" cols="30" rows="10"></textarea>
<input type="button" id="send" value="送出">
<div id="main"></div>

JS:

🎃 點擊「<input>按鈕」,就會觸發「onclick 事件」–> 然後,會把「<textarea>」裡面的內容(value),帶到<div id="main"></div>裡面去

1
2
3
4
document.getElementById('send').onclick = function(){
var str = document.getElementById('content').value;
document.getElementById('main').innerHTML = str;
}

🍋 <div id="main"></div>裡面,原本是「空的」

🍋 在「<textarea>」輸入一些內容(value),點擊「送出按鈕」後,內容就會帶到<div id="main"></div>裡面去

當我在寫 PHP 後端程式碼的時候,如果沒有先過濾資料,就很容易被駭客入侵 or 被竊取資料

駭客用.innerHTML入侵的方式有好幾種

‼️ 又稱為「XSS」:跨站指令攻擊(Cross-site scripting)

😈 方式一:直接入侵我的資料庫,把所有.innerHTML = 「等於」後面的值,都做改寫(改寫成駭客想要載入的 JavaScript 或檔案)

JS:

1
2
3
4
document.getElementById('send').onclick = function(){
var str = document.getElementById('content').value;
document.getElementById('main').innerHTML = str;
}

😈 方式二:

例如駭客會在<textarea>裡面,載入一些 JavaScript 語法

  • 案例一:駭客在<textarea>裡面,直接載入一支「all2.js」的檔案,來惡意攻擊原本的 JS 程式碼

  • 案例二:駭客在<textarea>裡面,直接用<script></script>寫一個alert()

‼️ 可以看到,除了加入「Hello!!!」之外,程式碼中就被埋了這個<script></script>

如果這些資料被送到後端資料庫,這個alert('你被入侵了')就會被執行

.innerHTML使用時機

✅ 可以使用.innerHTML

當我要撈取的資料是
🍋 來自於“我自己的網頁 or 後端資料庫”(是“可以信任的資料來源”)

🍋 接 open data 時(是“可以信任的資料來源”)

就可以使用.innerHTML去渲染出來

❌ 不使用.innerHTML

🍋 有「文字欄位」,user 可以去「操控、填寫」完,按下送出後再去做解析的,都會是「不可以信任的資料來源」

🎃 接收到 user 填寫的資料後,前後端都會去做一些「資料的過濾、排錯」,過濾掉一些「可疑的語法」,避免駭客去操縱資料庫

🎃 前端會先排錯一次(使用 framework),送到後端後,例如 Node.js 接收到前端傳來的資料後,也會再做一次排錯

例如:

  • 把「<」、「>」符號先過濾掉,再存到資料庫裡面

.createElement安全性高

原因為:

1
document.createElement('li');

例如,我用.createElement新增一個<li></li>

然後在<li></li>上面動態去增加「文字內容、屬性」等等


.createElement這種處理資料的方式,因為「每個動作都是分開的」,讓駭客比較難以對資料動手腳