一、原理
什么是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:對表單進項獲取之后,直接轉換為SQL語句進行數據數據庫查詢。
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
如果想username框中填寫admin,password為123
上面sql_select = " select * from users_userprofile where username='{0}' and passworf='{1}'
就相當於select * from users_userprofile where username=admin and passworf=123
進行查詢
但是
如果想username框中填寫admin or admin=admin #,password為123
如果想username框中填寫admin,password為123
上面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掉密碼和敏感的信息。