Django之CSRF XSS原理解析

目錄


CSRF

CSRF原理:安全驗證機制(跨域請求保護)
列子:假如A某在自己的電腦登錄了一個招商銀行的網站

1.我們再去點招商銀行該網站的其他頁面,是不需要繼續登錄的


2.服務端和客戶端是一個短連接,也就是客戶端發送請求以後,服務端回覆了以後鏈接就斷開了。可以這樣理解,客戶端發送了請求,服務端返回了數據,然後我們看到數據的時候,其實內部已經和服務器斷開了,相當於客戶端在服務端下載了數據,然後在自己的瀏覽器進行模板渲染。


3.然後我們再次點擊渲染數據內的鏈接,那麼等於重新發起一個請求,那麼問題來了請問服務器是如何確定還是A某點擊的?
解決這個問題,就是A某登錄的時候,服務端生成一個session id,然後把session id返回給了客戶端,客戶端在把session id存到瀏覽器cookie裏面去,每次A某的瀏覽器訪問的時候其實已經發送了這個session id給服務端了,所以服務端能確認是A某,就無需A某在登錄


4.此刻A某登錄另外一個AV網站,該AV網站也有自身的session id 放到了A某瀏覽器的cookie裏面 和招商網站的session id放在A某的cookie裏的沒任何關係。可以這樣比喻:AV網站在客戶端的瀏覽器創建了文件然後把session id放入這個文件,招商銀行的同理,所以是兩個網站的cookie是沒關係的,


5.由於安全機制,兩個cookie之間是隔離的,拿不到對方的cookie,瀏覽器是不允許的,如果av網站的cookie可以拿到招商的cookie拿就完蛋了,所以瀏覽器出了同源策略,


6.瀏覽器的同源策略:如果兩個頁面的協議,端口(如果有指定)和域名都相同,則兩個頁面具有相同的源。
簡單來說:(域名和A某的cookie判斷是否同源)也就是你訪問AV 該網站,只能從AV該網站之前存放A某客戶端的cookie拿到session id發送請求,而不能去拿招商cookie裏面的session id(因爲不同源)  

 
7都已經有同源策略了,爲什麼還需要CSRF?
    1)假如 A某進行轉賬請求:href=”icbc.com/transfer/account=A某,to=burgess,amount=1000” ---》招商網站
招商銀行拿到了請求也驗證了A某的session id,如果沒問題就完成了轉賬

    2)假如一個高級X某黑客,想要進行高破壞.但是又拿不到A某的招商cookie怎麼辦,就開始想辦法,
           -----1:截取請求url然後更改轉賬到自己名下?不可能銀行使用的是HTTPS,用抓包軟件是抓不到的,涉及到安全交易之類的網站都是加密的. 就算截獲了也是亂碼,現在不關是安全交易之類的網站連百度都使用了https
          -----2:X某知道了A某喜歡看AV網站,X某就建立了一個AV網站,X某知道A某會經常看他的AV網站,就在該AV網站的某個AV視頻埋下木馬(事件函數),就在A某打開該視頻鏈接在線觀看的時候,觸發了木馬事件函數(如是個a標籤超級鏈接
該標籤href=”icbc.com/transfer/account=A某,to=X某,amount=1000” )X某本身也是招行的客戶,知道招行發送請求的格式。這個時候招商銀行收到了請求,然後就進行了驗證用戶的session id(認爲是合法的)驗證就通過..然後錢就到了X某(注意這裏是A某的瀏覽器點擊發送的,所以是A某進行發送的)
其實X某的AV網站無非就是做了一個ajax鏈接而已,但是隻要你點擊就等同於你從你的瀏覽器發送了這個請求

所以怎麼辦?我們自己寫網站的都知道,你是看不出的,一個按鈕裏面觸發函數你是不知道了,
所以招行的服務器需要判定是不是從招行本身網站的頁面發送這條請求的,而不是通過別人網站頁面發送(這樣就OK了)
這就出現了CSRF機制了

1.所以我們第一次登陸訪問了招商銀行的頁面(get請求),那麼招商銀行生成一串值然後隨着頁面返回(相當於招商銀行的頁面多出了一個標籤存放這一串值),那麼如果你下一次發送post請求的時候,你必須帶着該頁面的這串值,一起提交否則無效

2.這次我們登錄了黑客的AV網站,我們點擊請求轉賬,黑客的網站頁面是沒有該串值的,所以請求是無效的
這串值就是csrf_token 我們可以理解成令牌或者口令(GET 獲取數據  冪等請求(沒涉及數據的修改))
form標籤內添加 csrf_token

submit提交自動把csrf_token進行提交(無需任何操作,但是ajax就需要進行獲取csrf_token進行提交)

ajax提交內添加csrf_token
方式1(獲取csrf進行請求頭髮送)

    <script src="/static/jquery.min.js"></script>
    <script src="/static/jquery.cookie.js"></script>
    <script>

            $('#ajax').click(function(){
                $.ajax({
                    url:'/login/',
                    type:"POST",
                    dataType:'JSON',
                    tradionale:true,
                    headers:{'X-CSRFtoken':$.cookie('csrftoken')},
                        //請求頭提交csrftoken
                    data:{'user':'root','pwd':'123'},
                    success:function (obj) {
                    }

                })
            })
        })
    </script>

方式2(前端添加一個自動函數,所有ajax提交之前都會執行該函數先進行提交csrf)

    <script src="/static/jquery.min.js"></script>
    <script src="/static/jquery.cookie.js"></script>
    <script>
        $(function(){
            function csrfSafeMethod(method){
                return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method))
            }
            $(function(){
               $.ajaxSetup({
                   beforeSend:function (xhr,settings) {
                       if(!csrfSafeMethod(settings.type) && !this.crossDomain)
                           xhr.setRequestHeader('X-CSRFtoken',$.cookie('csrftoken'))
                   }
               }) 
            });
//在執行ajax前會先執行$.ajaxSetup函數
//settings該形參是接收ajax提交的時候獲取到該ajax提交所有數據
//獲取了以後進行判斷請求類型是什麼傳參進行判斷
//如果是POST就先在ajax發送前先執行該ajaxSetup

            $('#ajax').click(function(){
                $.ajax({
                    url:'/login/',
                    type:"POST",
                    dataType:'JSON',
                    tradionale:true,
                    //headers:{'X-CSRFtoken':$.cookie('csrftoken')},
                    data:{'user':'root','pwd':'123'},
                    success:function (obj) {
                    }

                })
            })
        })
    </script>

 

XSS

XSS:就是用戶使用回覆進行寫標籤造成攻擊,但是這些默認都是不允許的,所以是小事(如,不停的彈框,或者嚴重的寫標籤偷偷的拿走了你的銀行登錄的cookie之類)

所以默認用戶提交會字符串顯示(失去標籤作用)

但是雖然上面可以避免Xss攻擊,但是有一些網站是需要用戶自己寫標籤的(如:博客網站就可以讓用戶寫標籤)

Xss攻擊(過濾的函數或類):
    博客網站,寫標籤格式提交的,服務器默認阻止,如:<h1>老子的博客</h1> 最終顯示也是以字符串形式顯示,但是我們需要顯示標籤的效果出來,實現2種方法,1 前端:字符串|safe 表示允許該字符串爲標籤 2後臺:mark_safe(字符串)、但是這也會出現問題,就是用戶提供了javasacrip的talert,用戶照樣能看到,所以必須要求用戶提交是安全的。解決:我們在頁面輸出沒法做安全機制,只能在用戶提交的時候做安全機制,把用戶提交過來的數據進行過濾(如:設置一個白名單,只有什麼標籤的什麼屬性纔可以通過驗證),

Django定義字符串標籤允許作爲標籤顯示:

前端

 

後臺

防止XSS攻擊(如論壇回覆使用標籤字符串回覆,這肯定不允許)
可過beautifulSoup4過濾標籤(白名單機制)

Django之Ajax(jQuery)and原生Ajax(XMLhttpRequest))【六】 https://blog.csdn.net/Burgess_zheng/article/details/86548396

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章