Django的安全攻擊

Django的安全攻擊

XSS

XSS(跨站腳本攻擊)

是一種常常出如今web應用中的計算機安全漏洞,它容許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中。也屬一種注入攻擊,注入本質上就是把輸入的數據變成可執行的程序語句好比這些代碼包括HTML代碼和客戶端腳本。python

危害

  • 盜取各種用戶賬號,如機器登陸賬號、用戶網銀賬號、各種管理員賬號
  • 控制企業數據,包括讀取、篡改、添加、刪除企業敏感數據的能力
  • 盜竊企業重要的具備商業價值的資料
  • 非法轉帳等

原理

  1. 反射型xss攻擊mysql

    通常的瀏覽器與服務器交互都是,客戶端向服務器發送一條請求,類http://ww.bigshop.com/product/list/?q=手機,也就是說客戶向目標站點發送了一條查詢全部手機的請求,而後服務器向客戶端返回相關數據,這是正常的。而且手機這一關鍵詞也會被從新返回給瀏覽器端的用戶,這就使得xss攻擊有隙可乘。黑客將http://ww.bigshop.com/product/list/?q=這條包含惡意腳本的連接經過某種方式發送給用戶,那麼用戶一旦點擊這條連接,就會向目標站點發送查詢``的請求,這固然是查詢不到任何結果,可是這段JavaScript的腳本就會從後臺轉了一圈又回到瀏覽器,這樣瀏覽器就會執行這段代碼,也就是是獲取用戶的cookie值。一旦黑客拿到你的cookie值,基本上就至關於能夠模擬你的身份。
    能夠看到,攻擊者巧妙地經過反射型XSS的攻擊方式,達到了在受害者的瀏覽器上執行腳本的目的。因爲代碼注入的是一個動態產生的頁面而不是永久的頁面,所以這種攻擊方式只在點擊連接的時候才產生做用,這也是它被稱爲非持久型XSS的緣由。程序員

  2. 存儲型xss攻擊web

    存儲型xss攻擊與反射型xss攻擊的區別在於,xss攻擊已經存儲在服務器的數據庫上,能夠長期的返回給瀏覽器端。例如當客戶A在博客園的博客或者評論區寫入一段js惡意腳本,這段腳本就會永久存儲到博客園的數據庫,一旦當有其餘用戶請求查看這條博客或者評論,博客園就會將相應的數據返回給用戶,固然這段js惡意腳本也會被返回給用戶的瀏覽器並執行。ajax

防禦

  • 字符過濾:對用戶的請求不管是url仍是表單提交的內容都進行長度檢查和對特殊字符進行過濾
  • cookie方面:避免在cookie中放入重要敏感信息
  • 表單提交:儘可能使用post的方式提交表單而不是get方式

不只服務器拿到用戶的請求進行過濾,在服務器將數據返回給瀏覽器後,瀏覽器也會再一次進行防禦。正則表達式

django中自動的幫咱們轉義好了數據, 不須要手動轉義sql

若是要給數據標記安全方式顯示,有以下兩中方法:數據庫

  1. 模版頁面上對拿到的數據後寫上safe. ----> {{XXXX|safe}}django

  2. 在後臺導入模塊:from django.utils.safestring import mark_safe

    把要傳給頁面的字符串作安全處理 ----> s = mark_safe(s)

csrf(Cross Site Request Forgery)

csrf(跨站域請求僞造)

CSRF 攻擊容許惡意用戶在另外一個用戶不知情或者未贊成的狀況下,以他的身份執行操做。

CSRF 攻擊是黑客藉助受害者的 cookie 騙取服務器的信任,可是黑客並不能拿到 cookie,也看不到 cookie 的內容。另外,對於服務器返回的結果,因爲瀏覽器同源策略的限制,黑客也沒法進行解析。所以,黑客沒法從返回的結果中獲得任何東西,他所能作的就是給服務器發送請求,以執行請求中所描述的命令,在服務器端直接改變數據的值,而非竊取服務器中的數據 。黑客沒法獲取cookie和session值更沒法進行解析。

過程

假如用戶A在某電商網站註冊過而且用戶本地瀏覽器又存在網站服務端頒發給本身的通行證(也就是cookie),那麼對於用戶A來講本身訪問網站而且提交請求購買商品都是暢通無阻,不須要身份驗證。可是黑客B想要利用A的帳戶給本身買東西,用戶B直接訪問電商網站固然沒法實現這一目的,緣由是B沒有A的通行證,想要利用A的帳戶在訪問網站時又不知道A的密碼。那麼B本身建造了一個黑客網站,這個黑客網站中存在跳轉向目標電商網站的黑客url連接,url連接又包含了用戶的請求(假如是A購買了一個iphone X發給某地址,固然這是B想要的地址)。當用戶訪問黑客網站時,點擊黑客連接時,目標網站就會接受到請求,因爲該請求是A的瀏覽器發出的,因此又包含A的cookie,服務端就會將一個iphone X發往B的地址,那麼黑客B的目的就達到了。因此在csrf中黑客B並不知道A的cookie,只是間接利用了cookie,拿着A的通行證瞞過目標網站,實現本身目的。

實現的方式

  1. 黑客網頁存在指向目標站點的連接,直接跳轉
  2. 黑客網頁包含動態加載的JavaScript,存在轉向目標站點的動做。
  3. 黑客網頁存在https://www.cnblogs.com/welan/p/xxx,其中xxx就是指向目標站點的連接,而且包含請求,例如 src=」<http://goumai.example/withdraw?account=A&goods=iphonex&for=B> 」

Django 提供的 CSRF 防禦機制

django 第一次響應來自某個客戶端的請求時(get方式),會在服務器端隨機生成一個 token,而後把這個 token 寫在用戶請求的 cookie 裏,同時也會給客戶端頁面發送一個隨機的 token (form表單中以{% csrf_token %}方式獲取)用以認證。以後客戶端每次以 POST 方式向服務端提交請求時,都會帶上這個 token,這樣就能避免被 CSRF 攻擊。

  1. 在返回的 HTTP 響應的 cookie 裏,django 會爲你添加一個 csrftoken 字段,其值爲一個自動生成的 token;
  2. 在全部的 POST 表單中,必須包含一個 csrfmiddlewaretoken 字段 (只須要在模板里加一個 tag, django 就會自動幫你生成,見下面)
  3. 在處理 POST 請求以前,django 會驗證這個請求的 cookie 裏的 csrftoken 字段的值和提交的表單裏的 csrfmiddlewaretoken 字段的值是否同樣。若是同樣,則代表這是一個合法的請求,不然,這個請求多是來自於別人的 csrf 攻擊,返回 403 Forbidden.
  4. 在全部 ajax POST 請求裏,添加一個 X-CSRFTOKEN header,其值爲 cookie 裏的 csrftoken 的值

Django 裏如何使用 CSRF 防禦

  • 首先,最基本的原則是:GET 請求不要用!有反作用!也就是說任何處理 GET 請求的代碼對資源的訪問都必定要是「只讀「的;

  • 其次,要啓用django.middleware.csrf.CsrfViewMiddleware 這個中間件;

  • 最後,在全部的 POST 表單元素中,須要加上一個{% csrf_token %}tag。

    緣由:用於csrf在模版渲染過程當中,會自動爲表單添加一個名爲 csrfmiddlewaretoken, type屬性爲 hidden 的 input。

# 1. 開啓全局的csrf驗證
    '''
    1. settings中,打開註釋 'django.middleware.csrf.CsrfViewMiddleware'
    2. 表單中,開啓csrf_token
    '''
    <form>
        {% csrf_token %}
        <input type='text'>
    </form>
    
    

# 2. 開啓全局的csrf,可是部分業務函數不進行檢驗
    '''
     1. settings中,打開註釋 ====》'django.middleware.csrf.CsrfViewMiddleware'
     2. views中,引入以下函數
    '''
    from django.views.decorators.csrf import csrf_exempt
    @csrf_exempt
    def csrf1(request):
        if request.method == 'GET':
            return render(request, 'csrf1.html')
        else:
            return HttpResponse('ok')

# 3. 關閉全局的csrf, 可是部分業務函數要使用csrf驗證
    '''
    1. settings中,註釋 ===》 #'django.middleware.csrf.CsrfViewMiddleware'
    2. views中,引入以下函數
    '''
    - FBV方式
    from django.views.decorators.csrf import csrf_protect
    @csrf_protect
    def csrf1(request):
        if request.method == 'GET':
            return render(request, 'csrf1.html')
        else:
            return HttpResponse('ok')
        
    - CBV
    from django.utils.decorators import method_decorator
    @method_decorator(csrf_protect, name='get')
    class User(View):
        def get(self, request):
            pass
        def post(self, request):
            pass
        
'''
ajax方式提交數據:
    <form method="POST" action="/csrf1.html/">
        {% csrf_token %}
        <input id="user" type="text" name="user" />
        <input type="submit" value="提交"/>
        <a onclick="submitForm();">Ajax提交</a>
    </form>
    
    1. 將token放置到請求頭中, 攜帶過來
        var token = $.cookie('csrftoken');
        var user = $('#user').val();
        $.ajax({
            type:'POST',
            url: '/csrf.html/',
            headers : {'X-CSRFToken': token}
            data:{'user':user},
        })

    2. 放置在data中攜帶
        var csrf = $('input[name="csrfmiddlewaretoken"]').val();
        var user = $('#user').val();
        $.ajax({
            type:'POST',
            url: '/csrf.html/',
            data:{'user':user,'csrfmiddlewaretoken': csrf},
        })
        
'''

sql注入攻擊

原理

什麼是sql注入

所謂SQL注入就是經過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串(注入本質上就是把輸入的字符串變成可執行的程序語句),最終達到欺騙服務器執行惡意的SQL命令。具體來講,它是利用現有應用程序,將(惡意的)SQL命令注入到後臺數據庫引擎執行的能力,它能夠經過在Web表單中輸入(惡意)SQL語句獲得一個存在安全漏洞的網站上的數據庫,而不是按照設計者意圖去執行SQL語句。在Web應用漏洞中,SQL Injection 漏洞的風險要高過其餘全部的漏洞。

相關原理

根據相關技術原理,SQL注入能夠分爲平臺層注入和代碼層注入。前者由不安全的數據庫配置或數據庫平臺的漏洞所致;後者主要是因爲程序員對輸入未進行細緻地過濾,從而執行了非法的數據查詢。

表現

SQL注入的產生緣由一般表如今如下幾方面:

  • 不當的類型處理;
  • 不安全的數據庫配置;
  • 不合理的查詢集處理;
  • 不當的錯誤處理;
  • 轉義字符處理不合適;
  • 多個提交處理不當。

案例

常見的就是進行登陸驗證的時候,表單提交的數據包含sql語句,代碼以下

# login.html

<h1>歡迎登錄<h1>
<from method='post' >
<input type='text' name='username' >
<input type='text' name='password'>
<input type="submit" value="當即登陸" > 
</form>
# views.py

from django.shortcuts import render, HttpResponse, redirect
from django.views.generic.base import View

class LoginNotSafeView(View):
    def get(self, request):
        return render(request, 'login.html')
    def post(self, request):
        user_name = request.POST.get("username", "")
        pass_word = request.POST.get("password", "")

        import pymysql
        conn = pymysql.connect(
            host='127.0.0.1', 
            port=3306, 
            user='root', 
            password='123456', 
            db='mxonline',
            charset='utf8' )
        cursor = conn.cursor()
        # 黑客可經過user或者password輸入數據庫語句對數據非法利用
        sql_select = " select * from users_userprofile where username='{0}' and passworf='{1}' ".format(user_name, pass_word)
        result = cursor.execute(sql_select)
        for i in cursor.fetchall():
            # 數據庫全部查詢結果
            pass
  1. 若是想username框中填寫adminpassword123

    上面sql_select = " select * from users_userprofile where username='{0}' and passworf='{1}'

    就至關於select * from users_userprofile where username=admin and passworf=123進行查詢

  2. 若是想username框中填寫admin or admin=admin #password123
    上面sql_select = " select * from users_userprofile where username='{0}' and passworf='{1}'

    就至關於select * from users_userprofile where username=admin or admin = admin # and passworf=123

    進行查詢
    這裏的#至關於把後面的全部查詢包括password查詢給註釋,而且or admin = admin的查詢永遠是正確的,因此sql攻擊注入就完成了

防範

  • 對用戶的輸入進行校驗,能夠經過正則表達式,或限制長度;對單引號和雙"-"進行轉換等。
  • 不要使用動態拼裝SQL,可使用參數化的SQL或者直接使用存儲過程進行數據查詢存取。
  • 不要使用管理員權限的數據庫鏈接,爲每一個應用使用單獨的權限有限的數據庫鏈接。
  • 不要把機密信息直接存放,加密或者hash掉密碼和敏感的信息。
相關文章
相關標籤/搜索