當前位置:
首頁 > 最新 > web前端安全與跨域

web前端安全與跨域

應後端同學要求,給大家分享一些稍微理論一點的知識,即前端跨域的知識。在講跨域之前,先介紹一下前端的安全。

安全

XSS攻擊(跨站腳本攻擊)

XSS(Cross Site Scripting),跨站腳本攻擊,XSS是常見的Web攻擊技術之一。所謂的跨站腳本攻擊指得是:惡意攻擊者往Web頁面里注入惡意script代碼,用戶瀏覽這些網頁時,就會執行其中的惡意代碼,可對用戶進行盜取cookie信息、會話劫持等各種攻擊。

反射型漏洞

一,例子說明:

1)通過程序參數輸出傳遞的參數到HTML頁面,則打開下面的網址將會返回一個消息提示: 請求:

返回:

2)如果此程序沒有經過過濾等安全措施,則它將會很容易受到攻擊。假如我們在原程序的URL的參數為,替換為我們用來測試的代碼: 請求:

返回:

這樣,用戶在瀏覽器打開的時候,就會運行我們的彈框了。由於這種漏洞需要發送一個包含了嵌入式JavaScript代碼的請求,隨後這些代碼被反射給了發出請求的用戶,因此被稱為反射型XSS。攻擊有效符合分別通過一個單獨的請求與響應進行傳送和執行,因為也被稱為一階XSS。

二,攻擊案例:

用戶正常登錄Web應用程序,登錄成功會得到一個會話信息的cookie:

攻擊者將含有攻擊代碼的URL發送給被攻擊人;

用戶打開攻擊者發送過來的ULR

Web應用程序執行用戶發出的請求,同時也會執行該URL中所含的攻擊者的JavaScript代碼;

例子中攻擊者使用的攻擊代碼作用是將用戶的cookie信息發送到cookie_save.php這個文件來記錄下來;

攻擊者在得到用戶的cookie信息後,將可以利用這些信息來劫持用戶的會話。以該用戶的身份進行登錄

存儲式漏洞

該類型是應用最為廣泛而且有可能影響到Web伺服器自身安全的漏洞,駭客將攻擊腳本上傳到Web伺服器上,使得所有訪問該頁面的用戶都面臨信息泄漏的可能,其中也包括了Web伺服器的管理員。 簡單來說明一下存儲型XSS的攻擊基本流程:

比如在某個論壇提供留言板功能,黑客在留言板內插入惡意的html或者Javascript代碼,並且提交。

網站後台程序將留言內容存儲在數據中

然後一個用戶也訪問這個論壇,並刷新了留言板,這時網站後台從資料庫中讀取了之前黑客的留言內容,並且直接插入在html頁面中,這就可能導致了:黑客留言的腳本本身應該作為內容顯示在留言板的,然後此時可能黑客的留言腳本被瀏覽器解釋執行了。

黑客的腳本可以用來他想要做的事情。例如通過javascript獲取用戶的cookie,根據這個cookie竊取用戶信息,例如重新更改頁面內容,假裝讓客戶輸入用戶名,密碼,然後提交到黑客的伺服器等。

防禦手段

不管是反射型還是存儲型,XSS攻擊的防禦方法主要是兩種 :

一,對輸入(和UR參數)進行過濾

二,對輸出進行編碼

也就是對提交的所有內容進行過濾,對url中的參數進行過濾,過濾掉會導致腳本執行的相關內容;然後對動態輸出到頁面的內容進行html編碼,使腳本無法在瀏覽器中執行。雖然對輸入過濾可以被繞過,但是也還是會攔截很大一部分的XSS攻擊。

CSRF

CSRF(Cross-site request forgery)跨站請求偽造,是一種對網站的惡意利用。儘管聽起來像跨站腳本(XSS),但它與XSS非常不同,XSS利用站點內的信任用戶,而CSRF則通過偽裝來自受信任用戶的請求來利用受信任的網站。與XSS攻擊相比,CSRF攻擊往往不大流行(因此對其進行防範的資源也相當稀少)和難以防範,所以被認為比XSS更具危險性。

攻擊案例:

用戶C打開瀏覽器,訪問受信任網站A,輸入用戶名和密碼請求登錄網站A;

在用戶信息通過驗證後,網站A產生Cookie信息並返回給瀏覽器,此時用戶登錄網站A成功,可以正常發送請求到網站A;

用戶未退出網站A之前,在同一瀏覽器中,打開一個TAB頁訪問網站B;

網站B接收到用戶請求後,返回一些攻擊性代碼,並發出一個請求要求訪問第三方站點A;

瀏覽器在接收到這些攻擊性代碼後,根據網站B的請求,在用戶不知情的情況下攜帶Cookie信息,向網站A發出請求。網站A並不知道該請求其實是由B發起的,所以會根據用戶C的Cookie信息以C的許可權處理該請求,導致來自網站B的惡意代碼被執行。

防禦手段:

目前防禦 CSRF 攻擊主要有三種策略:

1. 驗證 HTTP Referer 欄位:

根據 HTTP 協議,在 HTTP 頭中有一個欄位叫 Referer,它記錄了該 HTTP 請求的來源地址。

在通常情況下,訪問一個安全受限頁面的請求來自於同一個網站,比如需要訪問 http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory,用戶必須先登陸 bank.example,然後通過點擊頁面上的按鈕來觸發轉賬事件。這時,該轉帳請求的 Referer 值就會是轉賬按鈕所在的頁面的 URL,通常是以 bank.example 域名開頭的地址。而如果黑客要對銀行網站實施 CSRF 攻擊,他只能在他自己的網站構造請求,當用戶通過黑客的網站發送請求到銀行時,該請求的 Referer 是指向黑客自己的網站。因此,要防禦 CSRF 攻擊,銀行網站只需要對於每一個轉賬請求驗證其 Referer 值,如果是以 bank.example 開頭的域名,則說明該請求是來自銀行網站自己的請求,是合法的。如果 Referer 是其他網站的話,則有可能是黑客的 CSRF 攻擊,拒絕該請求。

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

CSRF 攻擊之所以能夠成功,是因為黑客可以完全偽造用戶的請求,該請求中所有的用戶驗證信息都是存在於 cookie 中,因此黑客可以在不知道這些驗證信息的情況下直接利用用戶自己的 cookie 來通過安全驗證。要抵禦 CSRF,關鍵在於在請求中放入黑客所不能偽造的信息,並且該信息不存在於 cookie 之中。可以在 HTTP 請求中以參數的形式加入一個隨機產生的 token,並在伺服器端建立一個攔截器來驗證這個 token,如果請求中沒有 token 或者 token 內容不正確,則認為可能是 CSRF 攻擊而拒絕該請求。

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

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

跨域

什麼是跨域:

跨域問題的產生,源於瀏覽器的安全設置。瀏覽器對於javascript的同源策略的限制,例如a.cn下面的js不能調用b.cn中的js,對象或數據(因為a.cn和b.cn是不同域),這樣可以一定程序上防止惡意程序的入侵,但也就引起了有正常需求的跨域問題了。

同源策略:

請求的url地址,必須與瀏覽器上的url地址處於同域上,也就是域名,埠,協議相同。如果我在本地上的域名是study.cn,請求另外一個域名一段數據,這個時候在瀏覽器上會報錯。跨域的解決方案有很多,目前常用的有:

圖片ping或script標籤跨域

一個網頁可以從任何網頁載入圖像,不用擔心跨域不跨域,所以,我們就可以利用圖片不受「同源限制」這一點進行跨域通信。

因為,我們可以利用JS創建一個新的Image對象,並把src屬性設置為指向請求的地址,通過監聽onload和onerror事件來確定是否接受到了響應。響應的數據可以是任意內容,但通常是像素圖或204響應。

這種方式優點是很明顯的:兼容性非常好,缺點就是:只能發生GET請求,而且無法獲取響應文本。

JSONP跨域

jsonp 全稱是JSON with Padding,是為了解決跨域請求資源而產生的解決方案,是一種依靠開發人員創造出的一種非官方跨域數據交互協議。

利用元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並不是 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。

CORS

跨域資源共享( CORS )機制允許 Web 應用伺服器進行跨域訪問控制,從而使跨域數據傳輸得以安全進行。瀏覽器支持在 API 容器中(例如 XMLHttpRequest 或 Fetch )使用 CORS,以降低跨域 HTTP 請求所帶來的風險。CORS 需要客戶端和伺服器同時支持。目前,所有瀏覽器都支持該機制。

與 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。伺服器一般需要增加如下響應頭的一種或幾種:

跨域請求默認不會攜帶Cookie信息,如果需要攜帶,請配置下述參數:

window.name+iframe

window.name通過在iframe(一般動態創建i)中載入跨域HTML文件來起作用。然後,HTML文件將傳遞給請求者的字元串內容賦值給window.name。然後,請求者可以檢索window.name值作為響應。

window.postMessage()

HTML5新特性,可以用來向其他所有的 window 對象發送消息。需要注意的是我們必須要保證所有的腳本執行完才發送 MessageEvent,如果在函數執行的過程中調用了它,就會讓後面的函數超時無法執行。

修改document.domain跨子域

前提條件:這兩個域名必須屬於同一個基礎域名!而且所用的協議,埠都要一致,否則無法利用document.domain進行跨域,所以只能跨子域。 在根域範圍內,允許把domain屬性的值設置為它的上一級域。例如,在」aaa.xxx.com」域內,可以把domain設置為 「xxx.com」 但不能設置為 「xxx.org」 或者」com」。

WebSocket

WebSocket protocol 是HTML5一種新的協議。它實現了瀏覽器與伺服器全雙工通信,同時允許跨域通訊,是server push技術的一種很棒的實現。

代理

同源策略是針對瀏覽器端進行的限制,可以通過伺服器端來解決該問題:

DomainA客戶端(瀏覽器) ==> DomainA伺服器 ==> DomainB伺服器 ==> DomainA客戶端(瀏覽器)

CORS跨域設置案例

我司採用的是CORS方案來進行跨域。

CORS需要瀏覽器和伺服器同時支持。整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對於開發者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感覺。因此,實現CORS通信的關鍵是伺服器。只要伺服器實現了CORS介面,就可以跨源通信。

瀏覽器將CORS請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。

只要同時滿足以下兩大條件,就屬於簡單請求。

簡單請求

對於簡單請求,瀏覽器直接發出CORS請求。具體來說,就是在頭信息之中,增加一個Origin欄位。

伺服器根據這個值,決定是否同意這次請求。

如果Origin指定的源,不在許可範圍內,伺服器會返回一個正常的HTTP回應。瀏覽器發現,這個回應的頭信息沒有包含Access-Control-Allow-Origin欄位,就知道出錯了,從而拋出一個錯誤,被XMLHttpRequest的onerror回調函數捕獲。注意,這種錯誤無法通過狀態碼識別,因為HTTP回應的狀態碼有可能是200。

如果Origin指定的域名在許可範圍內,伺服器返回的響應,會多出幾個頭信息欄位。

非簡單請求

非簡單請求的CORS請求,會在正式通信之前,增加一次HTTP查詢請求,稱為"預檢"請求(preflight)。

瀏覽器先詢問伺服器,當前網頁所在的域名是否在伺服器的許可名單之中,以及可以使用哪些HTTP動詞和頭信息欄位。只有得到肯定答覆,瀏覽器才會發出正式的XMLHttpRequest請求,否則就報錯。

伺服器收到"預檢"請求以後,檢查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers欄位以後,確認允許跨源請求,就可以做出回應。

參考文檔:

阿里云:https://yq.aliyun.com/ziliao/29368

CSDN安全博文:https://blog.csdn.net/stpeace/article/details/53512283

CSDN跨域博文:https://blog.csdn.net/ligang2585116/article/details/73072868

阮一峰老師:http://www.ruanyifeng.com/blog/2016/04/cors.html


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 insightLabs 的精彩文章:

協同開發h5和小程序

TAG:insightLabs |