Web 安全總結(面試必備良藥)

目錄

本文簡單介紹幾種常見的 web 安全問題:php

  • 同源策略
  • XSS
  • CSRF
  • SQL注入
  • 點擊劫持
  • window.opener 安全問題
  • 文件上傳漏洞

同源策略

若是兩個 URL 的協議、域名和端口都相同,咱們就稱這兩個 URL 同源。html

  • 同源策略限制了來自不一樣源的 JavaScript 腳本對當前 DOM 對象讀和寫的操做。
  • 同源策略限制了不一樣源的站點讀取當前站點的 Cookie、IndexDB、LocalStorage 等數據。
  • 同源策略限制了經過 XMLHttpRequest 等方式將站點的數據發送給不一樣源的站點。

解決同源策略的方法:前端

  • 跨文檔消息機制:能夠經過 window.postMessage 的 JavaScript 接口來和不一樣源的 DOM 進行通訊。
  • 跨域資源共享(CORS):跨域資源在服務端設置容許跨域,就能夠進行跨域訪問控制,從而使跨域數據傳輸得以安全進行。
  • 內容安全策略(CSP):主要以白名單的形式配置可信任的內容來源,在網頁中,可以使白名單中的內容正常執行(包含 JS,CSS,Image 等等),而非白名單的內容沒法正常執行。

XSS,跨站腳本攻擊(Cross Site Scripting)

存儲型 XSS 攻擊

利用漏洞提交惡意 JavaScript 代碼,好比在input, textarea等全部可能輸入文本信息的區域,輸入<script src="http://惡意網站"></script>等,提交後信息會存在服務器中,當用戶再次打開網站請求到相應的數據,打開頁面,惡意腳本就會將用戶的 Cookie 信息等數據上傳到黑客服務器。web

反射型 XSS 攻擊

用戶將一段含有惡意代碼的請求提交給 Web 服務器,Web 服務器接收到請求時,又將惡意代碼反射給了瀏覽器端,這就是反射型 XSS 攻擊。 在現實生活中,黑客常常會經過 QQ 羣或者郵件等渠道誘導用戶去點擊這些惡意連接,因此對於一些連接咱們必定要慎之又慎。正則表達式

Web 服務器不會存儲反射型 XSS 攻擊的惡意腳本,這是和存儲型 XSS 攻擊不一樣的地方。數據庫

基於 DOM 的 XSS 攻擊

基於 DOM 的 XSS 攻擊是不牽涉到頁面 Web 服務器的。它的特色是在 Web 資源傳輸過程或者在用戶使用頁面的過程當中修改 Web 頁面的數據。好比利用工具(如Burpsuite)掃描目標網站全部的網頁並自動測試寫好的注入腳本等。跨域

預防策略:瀏覽器

  1. 將cookie等敏感信息設置爲httponly,禁止Javascript經過document.cookie得到
  2. 對全部的輸入作嚴格的校驗尤爲是在服務器端,過濾掉任何不合法的輸入,好比手機號必須是數字,一般能夠採用正則表達式.
  3. 淨化和過濾掉沒必要要的html標籤,好比:<iframe>, alt,<script> ;淨化和過濾掉沒必要要的Javascript的事件標籤,好比:onclick, onfocus
  4. 轉義單引號,雙引號,尖括號等特殊字符,能夠採用htmlencode編碼 或者過濾掉這些特殊字符
  5. CSP,CSP 全稱爲 Content Security Policy,即內容安全策略。主要以白名單的形式配置可信任的內容來源,在網頁中,可以使白名單中的內容正常執行(包含 JS,CSS,Image 等等),而非白名單的內容沒法正常執行,從而減小跨站腳本攻擊(XSS),固然,也可以減小運營商劫持的內容注入攻擊。 配置方式:
//一、meta

<meta http-equiv="Content-Security-Policy" content="script-src 'self'">

//二、Http 頭部

Content-Security-Policy:
script-src 'unsafe-inline' 'unsafe-eval' 'self' *.54php.cn *.yunetidc.com *.baidu.com *.cnzz.com *.duoshuo.com *.jiathis.com;report-uri /error/csp
複製代碼

CSRF,跨站請求僞造(Cross-site request forgery)

引誘用戶打開黑客的網站,在黑客的網站中,利用用戶的登陸狀態發起的跨站請求。安全

發起 CSRF 攻擊的三個必要條件:服務器

  1. 目標站點必定要有 CSRF 漏洞;
  2. 用戶要登陸過目標站點,而且在瀏覽器上保持有該站點的登陸狀態;
  3. 須要用戶打開一個第三方站點,如黑客的站點等。

預防策略:

  1. 充分利用好 Cookie 的 SameSite 屬性。

SameSite 選項一般有 Strict、Lax 和 None 三個值。

  • SameSite 的值是 Strict,那麼瀏覽器會徹底禁止第三方 Cookie。
  • Lax 相對寬鬆一點。在跨站點的狀況下,從第三方站點的連接打開和從第三方站點提交 Get 方式的表單這兩種方式都會攜帶 Cookie。但若是在第三方站點中使用 Post 方法,或者經過 img、iframe 等標籤加載的 URL,這些場景都不會攜帶 Cookie。
  • 而若是使用 None 的話,在任何狀況下都會發送 Cookie 數據。 如:
set-cookie: 1P_JAR=2019-10-20-06; expires=Tue, 19-Nov-2019 06:36:21 GMT; path=/; domain=.google.com; SameSite=none
複製代碼
  1. 驗證請求的來源站點

在服務器端驗證請求來源的站點,就是驗證 HTTP 請求頭中的 OriginReferer 屬性。Referer 是 HTTP 請求頭中的一個字段,記錄了該 HTTP 請求的來源地址,而O rigin 屬性只包含了域名信息,並無包含具體的 URL 路徑。這是 Origin 和 Referer 的一個主要區別。

服務器的策略是優先判斷 Origin,若是請求頭中沒有包含 Origin 屬性,再根據實際狀況判斷是否使用 Referer 值。

  1. 在請求地址中添加 token 並驗證

CSRF 攻擊之因此可以成功,是由於黑客能夠徹底僞造用戶的請求,該請求中全部的用戶驗證信息都是存在於 cookie 中,所以黑客能夠在不知道這些驗證信息的狀況下直接利用用戶本身的 cookie 來經過安全驗證。所以要抵禦 CSRF,關鍵在於在請求中放入黑客所不能僞造的信息,而且該信息不存在於 cookie 之中。能夠在 HTTP 請求中以參數的形式加入一個隨機產生的 token,並在服務器端創建一個攔截器來驗證這個 token,若是請求中沒有 token 或者 token 內容不正確,則認爲多是 CSRF 攻擊而拒絕該請求。

  1. 在 HTTP 頭中自定義屬性並驗證

這種方法也是使用 token 並進行驗證,和上一種方法不一樣的是,這裏並非把 token 以參數的形式置於 HTTP 請求之中,而是把它放到 HTTP 頭中自定義的屬性裏。經過 XMLHttpRequest 這個類,能夠一次性給全部該類請求加上 csrftoken 這個 HTTP 頭屬性,並把 token 值放入其中。這樣解決了上種方法在請求中加入 token 的不便,同時,經過 XMLHttpRequest 請求的地址不會被記錄到瀏覽器的地址欄,也不用擔憂 token 會透過 Referer 泄露到其餘網站中去。

然而這種方法的侷限性很是大。XMLHttpRequest 請求一般用於 Ajax 方法中對於頁面局部的異步刷新,並不是全部的請求都適合用這個類來發起,並且經過該類請求獲得的頁面不能被瀏覽器所記錄下,從而進行前進,後退,刷新,收藏等操做,給用戶帶來不便。另外,對於沒有進行 CSRF 防禦的遺留系統來講,要採用這種方法來進行防禦,要把全部請求都改成 XMLHttpRequest 請求,這樣幾乎是要重寫整個網站,這代價無疑是不能接受的。

SQL注入

拼接 SQL 時未仔細過濾,黑客可提交畸形數據改變語義。好比查某個文章,提交了這樣的數據id=-1 or 1=1等。1=1 永遠是true,致使where語句永遠是ture.那麼查詢的結果至關於整張表的內容,攻擊者就達到了目的。或者,經過屏幕上的報錯提示推測 SQL 語句等。

預防策略:

  1. 禁止目標網站利用動態拼接字符串的方式訪問數據庫
  2. 減小沒必要要的數據庫拋出的錯誤信息
  3. 對數據庫的操做賦予嚴格的權限控制
  4. 淨化和過濾掉沒必要要的SQL保留字,好比:where, or, exec 等

點擊劫持

  • 誘使用戶點擊看似無害的按鈕(實則點擊了透明 iframe 中的按鈕).
  • 監聽鼠標移動事件,讓危險按鈕始終在鼠標下方.
  • 使用 HTML5 拖拽技術執行敏感操做(例如 deploy key).

預防策略:

  1. 服務端添加 X-Frame-Options 響應頭,這個 HTTP 響應頭是爲了防護用 iframe 嵌套的點擊劫持攻擊。 這樣瀏覽器就會阻止嵌入網頁的渲染。
  2. JS 判斷頂層視口的域名是否是和本頁面的域名一致,不一致則不容許操做,top.location.hostname === self.location.hostname
  3. 敏感操做使用更復雜的步驟(驗證碼、輸入項目名稱以刪除)。

window.opener 安全問題

window.opener 表示打開當前窗體頁面的的父窗體的是誰。例如,在 A 頁面中,經過一個帶有 target="_blank" 的 a 標籤打開了一個新的頁面 B,那麼在 B 頁面裏,window.opener 的值爲 A 頁面的 window 對象。

通常來講,打開同源(域名相同)的頁面,不會有什麼問題。但對於跨域的外部連接來講,存在一個被釣魚的風險。好比你正在瀏覽購物網站,從當前網頁打開了某個外部連接,在打開的外部頁面,能夠經過 window.opener.location 改寫來源站點的地址。利用這一點,未來源站點改寫到釣魚站點頁面上,例如跳轉到僞造的高仿購物頁面,當再回到購物頁面的時候,是很難發現購物網站的地址已經被修改了的,這個時候你的帳號就存在被釣魚的可能了。

預防策略:

  1. 設置 rel 屬性
<a href="https://xxxx" rel="noopener noreferrer"> 外鏈 <a>
複製代碼

rel=noopener 規定禁止新頁面傳遞源頁面的地址,經過設置了此屬性的連接打開的頁面,其 window.opener 的值爲 null。 2. 將外鏈替換爲內部的跳轉鏈接服務,跳轉時先跳到內部地址,再由服務器 redirect 到外鏈。 3. 能夠由 widow.open 打開外鏈。

文件上傳漏洞

服務器未校驗上傳的文件,導致黑客能夠上傳惡意腳本等方式。

預防策略:

  1. 用文件頭來檢測文件類型,使用白名單過濾(有些文件能夠從其中一部分執行,只檢查文件頭無效,例如 PHP 等腳本語言);
  2. 上傳後將文件完全重命名並移動到不可執行的目錄下;
  3. 升級服務器軟件以免路徑解析漏洞;
  4. 升級用到的開源編輯器;
  5. 管理後臺設置強密碼。

參考資料

  • 極客時間《瀏覽器工做原理與實踐》

最後

  • 歡迎加我微信(winty230),拉你進技術羣,長期交流學習...
  • 歡迎關注「前端Q」,認真學前端,作個有專業的技術人...

GitHub
相關文章
相關標籤/搜索