sql 註入風險 [TOC] 什麼是sql註入呢? 參考百度 查看sql註入風險 準備材料 示列 用戶的登錄模擬 select from userinfo;查看資料庫信息 select from userinfo where name = '凱歌318' and pwd = 666; 正常情況下 s ...
目錄
sql 註入風險
什麼是sql註入呢?
查看sql註入風險
- 準備材料
#創建一個用戶表
create table userinfo(id int primary key auto_increment,name char(12) unique not null,pwd int not null);
#寫入一個用戶信息用於下麵實驗
insert into userinfo(name,pwd) values('凱歌318',666);
#表結構
mysql> select * from userinfo;
+------+-----------+------+
| id | name | pwd |
+------+-----------+------+
| 1 | 凱歌318 | 666 |
+------+-----------+------+
1 row in set (0.00 sec)
示列 用戶的登錄模擬 select * from userinfo;查看資料庫信息
select * from userinfo where name = '凱歌318' and pwd = 666; 正常情況下
select * from userinfo where name = '凱歌318';-- and pwd = '我就是密碼';
在sql語言中 -- 表示註釋掉後邊的語句,所以只要我們知道賬戶,就能得到想要的結果,這就是sql註入風險
那你可能會想,還要知道賬戶才行,有沒有不需要賬戶,就能得到想要的結果呢?
當然有 select * from userinfo where name = '我不知道賬號' or 1=1;-- and password = '我就是密碼';
這種情況也是sql的註入風險
如何避免 sql 註入風險
1.永遠不要信任用戶的輸入。對用戶的輸入進行校驗,能夠通過正則表達式,或限制長度;對單引號和
雙"-"進行轉換等。檢查輸入的數據是否具有所期望的數據格式,嚴格限制變數的類型,例如使用regexp包進行一些匹配處理,
或者使用strconv包對字元串轉化成其他基本類型的數據進行判斷。
2.永遠不要使用動態拼裝sql,能夠使用參數化的sql或者直接使用存儲過程進行數據查詢存取。
3.永遠不要使用管理員許可權的資料庫連接,為每一個應用使用單獨的許可權有限的資料庫連接。
4.不要把機密信息直接存放。加密或者hash掉password和敏感的信息。對進入資料庫的特殊字元('"\尖括弧&*;等)進行轉義處理,
或編碼轉換
5.應用的異常信息應該給出儘可能少的提示,最好使用自己定義的錯誤信息對原始錯誤信息進行包裝,避免網站列印出SQL錯誤信息,
比如類型錯誤、欄位不匹配等,把代碼里的SQL語句暴露出來,以防止攻擊者利用這些錯誤信息進行SQL註入。
6.sql註入的檢測方法一般採取輔助軟體或站點平臺來檢測。軟體一般採用sql註入檢測工具jsky,站點平臺就有億思站點安全平臺檢測工具。
MDCSOFT SCAN等。採用MDCSOFT-IPS能夠有效的防禦SQL註入。XSS攻擊等。
7.嚴格限制Web應用的資料庫的操作許可權,給此用戶提供僅僅能夠滿足其工作的最低許可權,從而最大限度的減少註入攻擊對資料庫的危害。
8.在應用發佈之前建議使用專業的SQL註入檢測工具進行檢測,以及時修補被髮現的SQL註入漏洞。網上有很多這方面的開源工具,
例如sqlmap、SQLninja等。
9.所有的查詢語句建議使用資料庫提供的參數化查詢介面,參數化的語句使用參數而不是將用戶輸入變數嵌入到SQL語句中,
即不要直接拼接SQL語句。例如使用database/sql裡面的查詢函數Prepare和Query,或者Exec(query string, args ...interface{})。
pymysql 簡單規避註入風險示列
#錯誤示範 不要自己去拼接賬戶和密碼
import pymysql
conn = pymysql.connect(host='127.0.0.1', user='root', password='318', database='ftp')
cur = conn.cursor()
username = input('user >>>')
password = input('passwd >>>')
sql = "select * from userinfo where name = %s and password = %s ;"% (username, password)
cur.execute(sql)
print(cur.fetchone())
cur.close()
conn.close()
user >>>'我不知道賬號' or 1=1;--
passwd >>>我也不知道密碼
(1, '凱歌318', '666')
Process finished with exit code 0
#正確方法 cur.execute(sql, (username, password)) 把密碼和賬戶交給 execute去拼接
import pymysql
conn = pymysql.connect(host='127.0.0.1', user='root', password='318', database='ftp')
cur = conn.cursor()
username = input('user >>>')
password = input('pwd >>>')
sql = "select * from userinfo where name = %s and pwd = %s"
cur.execute(sql, (username, password))
print(cur.fetchone())
cur.close()
conn.close()
user >>>'我不知道賬號' or 1=1;--
pwd >>>也不知道密碼
None
Process finished with exit code 0
user >>>凱歌318
pwd >>>666
(1, '凱歌318', '666')
Process finished with exit code 0
作 者:郭楷豐
出 處:https://www.cnblogs.com/guokaifeng/
聲援博主:如果您覺得文章對您有幫助,可以點擊文章右下角 【推薦】一下。您的鼓勵是博主的最大動力!
自 勉:生活,需要追求;夢想,需要堅持;生命,需要珍惜;但人生的路上,更需要堅強。帶著感恩的心啟程,學會愛,愛父母,愛自己,愛朋友,愛他人。