常見的網站安全問題

常見的網站安全問題
通過一番 996,精心打造的網站眼看就要部屬上線了,但在網站正式上線以前,你有沒有想過本身的網站是否安全嗎?儘管你的網站用了不少高大上的技術,可是若是網站的安全性不足,沒法保護網站的數據,甚至成爲惡意程序的寄生溫牀,那前面堆砌了再多的美好也都成了枉然。數據庫

SQL 注入


在衆多安全性漏洞中,SQL注入絕對是最嚴重但也是最好處理的一種安全漏洞。在數據庫執行查詢句時,若是將惡意用戶給出的參數直接拼接在查詢句上,就有可能發生。後端

舉個例子,假設本來某網站登陸驗證的查詢句長這樣:跨域

strSQL = "SELECT * FROM users WHERE (name = '" + userName + "') and (pw = '"+ passWord +"');"

而惡意用戶輸入的參數爲:瀏覽器

userName = "1' OR '1'='1";
passWord = "1' OR '1'='1";

因爲代碼中是直接將參數與查詢句作字串作的拼接,因此 SQL 就成爲了這樣:安全

strSQL = "SELECT * FROM users WHERE (name = '1' OR '1'='1') and (pw = '1' OR '1'='1');"
// 至關於
strSQL = "SELECT * FROM users;"

這樣一來,帳號密碼就形同虛設,甚至能夠拿到整個數據庫的結構(SELECT * FROM sys.tables)、任意修改、查詢數據,整個網站的數據就所有泄露了。服務器

常見的網站安全問題
不過解決方法也很簡單,只要經過參數化查詢來避免直接將參數與查詢句拼接,並進行適當的輸入檢查、插入轉義字符、嚴格設定程序權限,就可以有效避免 SQL 注入了。ide

XSS


XSS(跨站***)也叫JavaScript 注入,是現代網站最頻繁出現的問題之一,它指的是網站被惡意用戶植入了其餘代碼,一般發生在網站將用戶輸入的內容直接放到網站內容時。例如論壇、留言板等能夠輸入任意文字的網站,惡意用戶若是寫入一小段 <script>,而且前、後端都沒有針對輸入內容作字符轉換和過濾處理,直接把用戶輸入的字串做爲頁面內容的話,就有可能遭到 XSS。網站

常見的 XSS 有幾個類型:將惡意代碼寫入數據庫,當數據被讀取出來時就會執行的儲存型XSS;將用戶輸入的內容直接帶回頁面上的反射型XSS;以及利用 DOM 的特性,各類花式執行惡意代碼的DOM-based型XSS。prototype

儲存型及反射型都很好理解,DOM-based 型就很是有意思了;能夠參考OSWAP 整理的XSS Filter Evasion Cheat Sheet,絕大多數的 XSS 方式,都是經過各個元素的 background-image 屬性或者元素上的各類事件回調來實現;其中特別值得注意的是 SVG,因爲 SVG 中能夠寫入任意 HTML,還能夠加上 onload 事件,若是把 SVG 當成普通圖片處理,直接做爲網站內容使用,若是遇到惡意用戶的話,後果不堪設想。因此在上線上傳圖片功能時,務必要把 SVG 過濾掉!code

避免 XSS 的方法其實也很簡單,只要在數據輸入輸出時作好字符轉換,使惡意代碼不被執行,而是被解析成字符就能夠了。

CSRF


CSRF(跨站請求僞造)是一種利用 Cookie 及 Session 認證機制進行***的手段;因爲 Session 認證的其實不是用戶本人,而是瀏覽器,那麼只要經過網頁DOM 元素能夠跨域的機制,對已經獲得認證的網站發出請求,就能夠假冒用戶,從而拿到敏感信息。

例如某家銀行的轉帳 API 的URL 是這樣的:

http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName

而惡意用戶若是在網站中塞進一個 <img /> 的話:

<img src="http://www.examplebank.com/withdraw?account=Alice&amount=1000&for=Badman">

當不知情的用戶瀏覽到***者的網站時,<img/> 會自動發出這個請求,若是用戶登陸銀行的 Session 還沒有過時,那麼這個請求極可能就會被銀行接受,最後會在用戶本人不知情的狀況下「被」轉賬。

這種***方式能夠與前面所說的 XSS 是相輔相成,例如在沒有防範 XSS 的論壇網站中植入 <img/>,那麼其 src 屬性就應該是獲取敏感信息的 API URL。

解決方法主要有如下幾種:

  • 檢查 Referer:在服務器端檢查請求頭中 Referer 的值,也就是檢查請求的來源,若是是來自容許的網站,纔會正常執行 API 的功能。
  • CSRF Token:在 Cookie 及請求發送的數據中都加上 csrftoken,並檢查值是否相同,若是請求來源是本身的網站驗證就會經過;反之,因爲外部網站沒法在代碼中獲得其餘網站的 Cookie,所以沒法在請求中帶上 csrftoken。
  • SameSite Cookie:在 Cookie 中加上 SameSite 屬性,確保 Cookie 僅能在本身的網站使用。

    JSON 劫持


JSON 劫持是利用現代網站先後端經過 API 進行數據交換的特性,只要能得到使用者權限,並調用獲取資料的 API,再加上改寫原生的 JavaScript 對象,就能夠竊取用戶的敏感信息。

得到權限的部分於 CSRF 相同,經過 <script> 能夠跨域的特性直接使用瀏覽器用戶的 Cookie;***者只須要在網頁上經過 <script> 調用獲取數據的 API 完成對數據的竊取。

例如:

Object.prototype.__defineSetter__('user',function(obj){
  for(var i in obj) {
    alert(i + '=' + obj[i]);
  }
});

當回傳的數據中含有 user 屬性時,因爲 Setter 經過 Object.prototype.defineSetter 改寫了,user 中的值會被所有讀取。

然而 Object.prototype.defineSetter 能夠修改原生對象所形成的問題,早已經在 ES4 中就被修復了,JSON 劫持也所以銷聲匿跡,可是從 ES6 開始又添加了 Proxy,使 JSON 劫持又再次成爲可能:

<script>
<script>
  Object.setPrototypeOf(
    __proto__,
    new Proxy(__proto__, {
      has: function(target, name) {
        alert(
          name.replace(/./g, function(c) {
            c = c.charCodeAt(0)
            return String.fromCharCode(c >> 8, c & 0xff)
          })
        )
      }
    })
  )
</script>
<script charset="UTF-16BE" src="external-script-with-array-literal"></script>

看起來很恐怖,那麼該如何解決呢?除了前面所說的 CSRF Token 外,許多大公司還採用了另外一種有趣的解決方式。即 API 的響應內容開頭爲 for (;;);,這也是利用 了<script> 引入的 JavaScript 會當即執行的特性,把***者的網站卡死在循環裏。

總結


除了文中提到的四種常見的網站安全漏洞外,一個網站還有不少細節須要考慮,例如不要用明碼存儲密碼等敏感信息,針對來源 IP 作流量限制防止 DOS 等等。因此在進行網站開發時要保持安全意識,儘量作好基本的防禦措施。

相關文章
相關標籤/搜索