XSS
XSS 全稱「跨站腳本」,是注入攻擊的一種。前端
其特色是不對服務器端形成任何傷害,而是經過一些正常的站內交互途徑,例如發佈評論,提交含有 JavaScript 的內容文本。ajax
這時服務器端若是沒有過濾或轉義掉這些腳本,做爲內容發佈到了頁面上,其餘用戶訪問這個頁面的時候就會運行這些腳本。json
我把全部用戶輸入進行 HTML 轉義輸出是個不錯的作法。彷佛不少 Web 開發框架、模版引擎的開發者也發現了這一點,Django 內置模版和 Jinja2 模版老是默認轉義輸出變量的。api
大多數 Web 開發者都瞭解 XSS 並知道如何防範,每每大型的 XSS 攻擊都是因爲疏漏。。跨域
XSS 是實現 CSRF 的諸多途徑中的一條,但絕對不是惟一的一條。通常習慣上把經過 XSS 來實現的 CSRF 稱爲 XSRF瀏覽器
CSRF
CSRF 並不必定要有站內的輸入,由於它並不屬於注入攻擊,而是請求僞造。被僞造的請求能夠是任何來源,而非必定是站內。安全
因此咱們惟有一條路可行,就是過濾請求的 處理者。服務器
對於發佈帖子這一類建立資源的操做,應該只接受 POST 請求,而 GET 請求應該只瀏覽而不改變服務器端資源。固然,併發
最理想的作法是使用 REST 風格 的 API 設計,app
GET、POST、PUT、DELETE 四種請求方法對應資源的讀取、建立、修改、刪除。
如今的瀏覽器基本不支持在表單中使用 PUT 和 DELETE 請求方法,
咱們可使用 ajax 提交請求。也可使用隱藏域指定請求方法,
而後用 POST 模擬 PUT 和 DELETE (Ruby on Rails 的作法)。這麼一來,不一樣的資源操做區分的很是清楚
令牌方法
首先服務器端要以某種策略生成隨機字符串,做爲令牌(token), 保存在 Session 裏。
而後在發出請求的頁面,把該令牌以隱藏域一類的形式,與其餘信息一併發出。
在接收請求的頁面,把接收到的信息中的令牌與 Session 中的令牌比較,
只有一致的時候才處理請求,
不然返回 HTTP 403 拒絕請求
或者要求用戶從新登錄驗證身份。
CORS是一個W3C標準,全稱是」跨域資源共享」(Cross-origin resource sharing)。
它容許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。
即爲瀏覽器限制訪問A站點下的js代碼對B站點下的url進行ajax請求。
好比說,前端域名是www.abc.com,
那麼在當前環境中運行的js代碼,出於安全考慮,訪問www.xyz.com域名下的資源,是受到限制的。
現代瀏覽器默認都會基於安全緣由而阻止跨域的ajax請求,這是現代瀏覽器中必備的功能,
可是每每給開發帶來不便。瀏覽器將CORS請求分紅兩類:
簡單請求(simple request)和非簡單請求(not-so-simple request)。
只要同時知足如下兩大條件,就屬於簡單請求。
1) 請求方法是如下三種方法之一:
HEAD
GET
POST
2)HTTP的頭信息不超出如下幾種字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
對於簡單請求,瀏覽器直接發出CORS請求。具體來講,就是在頭信息之中,增長一個Origin字段。
Origin字段用來講明,本次請求來自哪一個源(協議 + 域名 + 端口)。服務器根據這個值,決定是否贊成此次請求。
若是Origin指定的源,**不在許可範圍內**,服務器會返回一個正常的HTTP迴應。
若是這個迴應的頭信息沒有包含Access-Control-Allow-Origin字段,
就知道出錯了,從而拋出一個錯誤,被XMLHttpRequest的onerror回調函數捕獲。這種錯誤沒法經過狀態碼識別,由於HTTP迴應的狀態碼有多是200
若是Origin指定的域名**在許可範圍內**,服務器返回的響應,會多出幾個頭信息字段。
1)Access-Control-Allow-Origin
該字段是必須的。它的值要麼是請求時Origin字段的值,要麼是一個*,表示接受任意域名的請求。
(2)Access-Control-Allow-Credentials
該字段可選。它的值是一個布爾值,表示是否容許發送Cookie。
默認狀況下,Cookie不包括在CORS請求之中。
設爲true,即表示服務器明確許可,Cookie能夠包含在請求中,一塊兒發給服務器。這個值也只能設爲true,
若是服務器不要瀏覽器發送Cookie,刪除該字段便可。
(3)Access-Control-Expose-Headers
該字段可選。CORS請求時,XMLHttpRequest對象的getResponseHeader()方法
只能拿到6個基本字段:
Cache-Control、
Content-Language、
Content-Type、
Expires、
Last-Modified、
Pragma。
若是想拿到其餘字段,就必須在Access-Control-Expose-Headers裏面指定。上面的例子指定,getResponseHeader('FooBar')能夠返回FooBar字段的值。
非簡單請求是那種對服務器有特殊要求的請求,好比請求方法是PUT或DELETE,或者Content-Type字段的類型是application/json。
瀏覽器發現,這是一個非簡單請求,就自動發出一個」預檢」請求,要求服務器確承認以這樣請求。
「預檢」請求用的請求方法是OPTIONS,表示這個請求是用來詢問的。頭信息裏面,關鍵字段是Origin,表示請求來自哪一個源。
除了Origin字段,」預檢」請求的頭信息包括兩個特殊字段。
(1)Access-Control-Request-Method
該字段是必須的,用來列出瀏覽器的CORS請求會用到哪些HTTP方法,上例是PUT。
(2)Access-Control-Request-Headers
該字段是一個逗號分隔的字符串,指定瀏覽器CORS請求會額外發送的頭信息字段,如:X-Custom-Header。
HTTP迴應中,關鍵的是Access-Control-Allow-Origin字段,表示http://api.bob.com能夠請求數據。該字段也能夠設爲星號,表示贊成任意跨源請求。
否認了」預檢」請求,會返回一個正常的HTTP迴應,可是沒有任何CORS相關的頭信息字段。
這時,瀏覽器就會認定,服務器不一樣意預檢請求,所以觸發一個錯誤,被XMLHttpRequest對象的onerror回調函數捕獲。