在用pymysql模組操作驗證註冊登陸的時候,涉及字串拼接時容易出現明明賬戶密碼不對的情況sql語句還是可以被執行,這樣就導致使用者可以繞開賬戶密碼就能進入資料庫。廢話不說,看圖:
sql**為:
user = input('賬戶:').strip()
pwd = input('密碼:').strip()
sql = 'select * from register where name = "%s" and pwd ="%s"' %(user,pwd)
res = cursor.execute(sql)
if res == 1:
print('登陸成功')
print(cursor.fetchall())
else:
print('登陸失敗')
換另一種『錯誤』的賬號看結果:
上面』賬戶『至少mcc還是正確的,再來乙個』完全不沾邊『的賬戶
原因是什麼呢?
根本原因在於mysql的注釋語法 – ,上面的兩張圖顯示了兩種sql注入情況,第一種是使用者存在,繞過密碼,第二種情況使用者不存在,繞過使用者與密碼
看一下第一種情況的sql語句:
select * from register where name = "mcc" -- sdadadf" and pwd =""
資料庫中,-- 後的所有內容都被注釋掉,即使再輸入密碼也是沒用的,最後的sql語句是select * from register where name = 「mcc」,這句sql語句可以被正確執行,也能查出mcc的結果
select * from register where name = "***" or 1=1 -- saddjna" and pwd =""
在資料庫中,-- 後面的條件全部被注釋掉,where 的過濾條件就剩name=「***」 or 1=1,1=1顯然永遠成立,where的最終過濾條件就是true,sql執行的就是select * from register 。
解決方法
原來是我們對sql進行字串拼接
sql=『select * from register where name="%s" and password="%s"』 %(user,pwd)
res=cursor.execute(sql)
#改寫為(execute幫我們做字串拼接,我們無需且一定不能再為%s加引號了)
sql="select * from register where name=%s and password=%s"
#!!!注意%s需要去掉引號,因為pymysql會自動為我們加上res=cursor.execute(sql,[user,pwd])
#pymysql模組自動幫我們解決sql注入的問題,只要我們按照pymysql的規矩來。 動態SQL和PL SQL的EXECUTE選項分析
execute immediate代替了以前oracle8i中dbms sql package包.它解析並馬上執行動態的sql語句或非執行時建立的pl sql塊.動態建立和執行sql語句效能超前,execute immediate的目標在於減小企業費用並獲得較高的效能,較之以前它相當容易編碼.儘管d...
動態SQL和PL SQL的EXECUTE選項分析
execute immediate代替了以前oracle8i中dbms sql package包.它解析並馬上執行動態的sql語句或非執行時建立的pl sql塊.動態建立和執行sql語句效能超前,execute immediate的目標在於減小企業費用並獲得較高的效能,較之以前它相當容易編碼.儘管d...
動態SQL和PL SQL的EXECUTE選項分析
url execute immediate代替了以前oracle8i中dbms sql package包.它解析並馬上執行動態的sql語句或非執行時建立的pl sql塊.動態建立和執行sql語句效能超前,execute immediate的目標在於減小企業費用並獲得較高的效能,較之以前它相當容易編碼...