2017-09-26 83 views
-1

我用這個驗證:防止在Django SQL注入形成

class MyValidationForm(forms.Form): 
    title = forms.CharField() 
    body = forms.Textarea() 
    taxonomy = forms.IntegerField() 

,這是我基於類的觀點:

class blog_createpost(dashboardBaseViews): 

template_name = "dashboardtems/blog_createpost.html" 

model = {} 

def post(self, request, *args, **kwargs): 

    form = MyValidationForm(request.POST) 

    if not form.is_valid(): 
     return HttpResponse("not valid") 


    new_data = post(title=request.POST['title'], 
        body=request.POST['body'], 
        description=request.POST['description'], 
        taxonomy=get_object_or_404(taxonomy, 
         pk=request.POST['taxonomy']), 
        writer=request.user) 
    new_data.save() 
    return HttpResponse("done") 

就像你看到我檢查我收到請求驗證這一行:if not form.is_valid():和它的工作,但是當我在表單輸入中添加一些SQL-command。它不會阻止將值插入數據庫! 意味着我在數據庫中有一個字段,其中包含一些值,如select * from user where 1=1!。 不會導致它從用戶輸入的SQL注入的危險?...

+3

Django已經可以保護您免受SQL注入攻擊。是的,看起來像SQL命令的* data *被插入到數據庫中,這是對這些數據的正確響應。一次成功的SQL注入攻擊會執行SQL,而不是將其作爲數據插入。 –

+1

請注意,使用模型表單的一個要點是您可以使用'form.save()'來創建您的發佈對象。無論如何,你應該總是訪問'form.cleaned_data'而不是'request.POST'。 –

+0

這就是爲什麼我們使用像Django這樣的框架。沒有必要重新發明輪子。該框架不僅注意SQL注入,還注意XSS,CSRF,表單驗證等等。您應該花更多時間閱讀文檔並瞭解該工具。 – cezar

回答

4

你誤會了SQL注入意味着。 Django已成功保護您免受此類攻擊,字符串"select * from user where 1=1"被視爲數據,而不是作爲命令,並最終成爲數據庫中的值。

SQL注入攻擊更改數據庫正在執行的SQL。取而代之的是,成功的攻擊誘使數據庫執行數據。您不會以select * from user where 1=1作爲價值,但是最終攻擊者可以訪問user表中的所有結果。

一個經典的錯誤是通過將SQL命令構造爲字符串來不正確地轉義數據。比方說服務器使用下面的查詢查找數據爲當前用戶:

SELECT * FROM user WHERE username='$user_id' 

其中$user_id來自請求。通常這會是一個登錄名,說

user_id = "zopatista" 

使查詢變得

SELECT * FROM user WHERE username='zopatista' 

如果服務器不能防止SQL注入攻擊,攻擊者可以代替user_id注入更多的SQL命令

user_id = "zopatista' OR 1=1 -- " 

所以以後乾脆插即串入查詢,現在服務器將發送以下SQL來數據庫:

SELECT * FROM user WHERE username='zopatista' OR 1=1 -- ' 

突然查詢命令的意義已經改變和數據庫將返回所有行,而不是僅僅一排匹配的登錄名。

classic XKCD joke on SQL injection更進一步,並注入SQL代碼,刪除整個表,而不是嘗試訪問更多的信息。

服務器防範SQL注入將確保用戶提供的數據始終是參數化,將數據從單獨的查詢發送到數據庫驅動程序,以確保它永遠不能被看作是查詢的一部分。

只要您使用Django的模型和查詢集,就可以避免SQL注入攻擊。如果您將extra()RawSQL()與用戶數據混合,而不使用其參數功能,則只會存在風險。

+0

tnx ...爐排說明 –

+0

感謝您的解釋@Martijn彼得斯。目前我在我的視圖中注入了SQL,因爲我不明白如何從Django模型中獲取數據。我需要根據兩個數據庫表之間的連接提取細節。你可以給我一些關於如何用一些基於模型的查詢替換SQL查詢的提示嗎? – NSP

+0

@NSP:這太方便了,太寬泛了。 Django的ORM保護您免受注入,並支持連接。見https://docs.djangoproject.com/en/1.11/topics/db/queries/ –