php csrf攻击 xss区别,XSS与CSRF攻击及防御方法
前言
web安全這詞可能對于服務端工程師來說更加“眼熟”,部分前端工程師并不是十分了解,今天就來講講XSS攻擊與CSRF攻擊及防御方法
XSS
XSS (Cross Site Scripting),即跨站腳本攻擊,是一種常見于 Web 應用中的計算機安全漏洞。大部分的XSS 漏洞都來自于程序沒有處理好用戶輸入的文本內容,惡意攻擊者往 Web 頁面里嵌入惡意的客戶端腳本,當用戶瀏覽此網頁時,腳本就會在用戶的瀏覽器上執行,從而達到攻擊者的目的。比如獲取用戶的 Cookie、導航到惡意網站、攜帶木馬等等!
XSS 腳本攻擊案例:
新浪微博遭受 XSS 攻擊
人人網遭受 XSS 攻擊
實例
測試XSS攻擊$(document).ready(function(){
$("#tijiao").click(function(){
var content = $("#username").val();
$('#name').html(content);
});
});
你的姓名:
提交
用戶姓名:
正常用戶的姓名肯定是不會有問題,但是假如用戶姓名是:
張三
//甚至
張三
就這樣很簡單的通過前端頁面來獲取用戶在網站中的信任數據,然后通過自己的腳本文件去執行自己的操作!
XSS防御
一個經典的防御方法就是對內容進行轉義和過濾,比如
var escapeHtml = function(str) {
if(!str) return '';
str = str.replace(/&/g, '&');
str = str.replace(/
str = str.replace(/>/g, '>');
str = str.replace(/"/g, '&quto;');
str = str.replace(/'/g, ''');
// str = str.replace(/ /g, ' ');
return str;
};
var name = escapeHtml(`張三`);
此時 name 中那段腳本代碼就會變成:
"張三<script>alert(document.cookie)</script>";
雖然在頁面渲染沒有變化,但是腳本卻不在執行,直接顯示為
用戶姓名:張三
需要用富文本可能稍微麻煩一些,因為要保留一部分標簽和屬性,這種場景的話就只能指定部分的標簽和屬性能夠添加,其他的一律轉義,部分不支持的標簽或者屬性讓用戶處理成圖片格式上傳至富文本!
當然,我們要轉義的不僅僅只是頁面數據的渲染,還有請求接口的參數、來自第三方鏈接,甚至后臺返回的數據都應該轉義一下!更多轉義的策略需要在實際開發中有更多的摸索!
總之,如果開發者沒有將用戶輸入的文本進行合適的過濾,就貿然插入到 HTML 中,這很容易造成注入漏洞。攻擊者可以利用漏洞,構造出惡意的代碼指令,進而利用惡意代碼危害數據安全。
CSP防御
現代瀏覽器為我們帶來了一個全新的安全策略,叫作內容安全策略,Content Security Policy,簡稱CSP。CSP的思路跟轉義不一樣,它的著手點是,如果一段代碼變成了程序,我們是否應該運行它。或者更準確一點說,它實際上是定義頁面上哪一些內容是可被信任的,哪一些內容是不被信任的。
因為我們自己的腳本是預先就知道并放在頁面上的,所以我們可以設置好信任關系,當有 XSS 腳本出現時,它并不在我們的信任列表中,因此可以阻止它運行。
它的具體使用方式是在 HTTP 頭中輸出 CSP 策略:
Content-Security-Policy: ;
從語法上可以看到,一個頭可以輸出多個策略,每一個策略由一個指令和指令對應的值組成。指令可以理解為指定內容類型的,比如script-src指令用于指定腳本,img-src用于指定圖片。值則主要是來源,比如某個指定的URL,或者self表示同源,或者unsafe-inline表示在頁面上直接出現的腳本等。
Content-Security-Policy: script-src 'self';
這樣除了在同一個域名下的JS文件外,其它的腳本都不可以執行了,自然之前 XSS 的內容也就失效啦。簡單粗暴有沒有?
當然,如果需要添加內聯的腳本,CSP 只需要指定一個 nonce 屬性,或者計算一下 hash 值,即可。詳細的用法看 MDN
CSRF
CSRF(Cross-site request forgery)跨站請求偽造:攻擊者誘導受害者進入第三方網站,在第三方網站中,向被攻擊網站發送跨站請求。利用受害者在被攻擊網站已經獲取的注冊憑證,繞過后臺的用戶驗證,達到冒充用戶對被攻擊的網站執行某項操作的目的。
當一個用戶登錄我們的網站后,在 Cookies 中會存放用戶的身份憑證。在大部分時候,就是一個 SessionId 。當用戶下次訪問我們的網站的時候,我們用這個憑證識別出用戶是誰,有沒有登錄態。
一個典型的攻擊流程:
受害者登錄a.com,并保留了登錄憑證(Cookie)。
攻擊者引誘受害者訪問了b.com。
b.com 向 a.com 發送了一個請求:a.com/act=xx。
a.com接收到請求后,對請求進行驗證,并確認是受害者的憑證及Cookie中的Session_id,誤以為是受害者自己發送的請求。
a.com以受害者的名義執行了act=xx。
攻擊完成,攻擊者在受害者不知情的情況下,冒充受害者,讓a.com執行了自己定義的操作。
模擬過程如:
Title特點
攻擊一般發起在第三方網站,而不是被攻擊的網站。被攻擊的網站無法防止攻擊發生。
攻擊利用受害者在被攻擊網站的登錄憑證,冒充受害者提交操作;而不是直接竊取數據。
整個過程攻擊者并不能獲取到受害者的登錄憑證,僅僅是“冒用”。
跨站請求可以用各種方式:圖片URL、超鏈接、Form提交等等。部分請求方式可以直接嵌入在第三方論壇、文章中,難以進行追蹤。
CSRF通常是跨域的,因為外域通常更容易被攻擊者掌控。但是如果本域下有容易被利用的功能,比如可以發圖和鏈接的論壇和評論區,攻擊可以直接在本域下進行,而且這種攻擊更加危險。
CSRF的防御
盡量使用POST,限制GET
GET接口太容易被拿來做CSRF攻擊,看一個示例就知道:
銀行網站A,它以GET請求來完成銀行轉賬的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000
危險網站B,它里面有一段HTML的代碼如下:
只要構造一個img標簽,而img標簽又是不能過濾的數據。接口最好限制為POST使用,GET則無效,降低攻擊風險。當然POST并不是萬無一失,攻擊者只要構造一個form就可以。
驗證碼
驗證碼,強制用戶必須與應用進行交互,才能完成最終請求。在通常情況下,驗證碼能很好遏制CSRF攻擊。但是出于用戶體驗考慮,網站不能給所有的操作都加上驗證碼,只有那些特別敏感的操作需要加上。因此驗證碼只能作為一種輔助手段,不能作為主要解決方案。
同源檢測
既然CSRF大多來自第三方網站,那么我們就直接禁止外域(或者不受信任的域名)對我們發起請求。
Origin Header
Referer Header
這兩個Header在瀏覽器發起請求時,大多數情況會自動帶上,并且不能由前端自定義內容。服務器可以通過解析這兩個Header中的域名,確定請求的來源域。如果Origin和Referer都不存在,建議直接進行阻止!
Token驗證
后端人員可以在HTTP請求中以參數的形式加入一個隨機產生的token,放入cookie中,然后前端在請求過程中把token帶上,最后服務端進行token校驗,如果請求中沒有token或者token內容不正確,則認為是CSRF攻擊而拒絕該請求。(注:當網站同時存在XSS漏洞時候,那這個方案也是空談。所以XSS帶來的問題,應該使用XSS的防御方案予以解決)
從上面也能看出大部分的防御工作還是需要服務端來進行,作為前端工程師需要最大限度的配合服務端進行安全防御措施!
以上重點講了 XSS 和 CSRF 這兩種比較常見的前端安全問題的防御思路,尤其是如何使用一些新的規范、實現來幫助我們進行防御。希望后面瀏覽器對這些安全相關防御辦法的普及率能再高一些,讓前端工程師能花更少的時間寫出更安全的代碼。
參考網站:
如何防止XSS攻擊?--美團技術團隊
如何防止CSRF攻擊?--美團技術團隊
總結
以上是生活随笔為你收集整理的php csrf攻击 xss区别,XSS与CSRF攻击及防御方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python写的贪吃蛇小游戏_Pytho
- 下一篇: 串行口实验 编写程序利用PC机控制单片