什么是sql注入
圖片來源:百度百科
python 操作mysql產生sql注入問題
不用ORM框架,框架中已經集成了防范sql注入的功能,使用pymysql實踐一下:
# 導入pymysql模塊 import pymysql # 連接database conn = pymysql.connect(host='127.0.0.1', user='root',password='root',database='oss2_base_test',charset='utf8') # 得到一個可以執行SQL語句的光標對象 cursor = conn.cursor() # 定義要執行的SQL語句 proj_id = "146" sql = "SELECT * FROM oss2_base_test.auto_task where proj_id={};".format(proj_id) # 執行SQL語句 cursor.execute(sql) result = cursor.fetchall() print(result) # 關閉光標對象 cursor.close() # 關閉數據庫連接 conn.close()
上面的sql最終被轉為了:sql = "SELECT * FROM oss2_base_test.auto_task where proj_id='146';
符合預期,執行也是沒有問題的
sql注入攻擊:
sql = "SELECT * FROM oss2_base_test.auto_task where proj_id={};".format("'' or 1=1")
上面語句被轉為:"SELECT * FROM oss2_base_test.auto_task where proj_id='' or 1=1;"
這將導致表中所有數據都被讀取出來,造成的壓力可想而知
我們如果涉及到只取部分數據,用limit限制,看sql注入攻擊如何寫:
正常查詢:sql = "SELECT * FROM oss2_base_test.auto_task where proj_id={} limit 5;".format("146")
最終被轉為:sql = "SELECT * FROM oss2_base_test.auto_task where proj_id='146' limit 5;"
sql注入:sql = "SELECT * FROM oss2_base_test.auto_task where proj_id={} limit 5;".format("'' or 1=1#")
最終轉化為:sql = "SELECT * FROM oss2_base_test.auto_task where proj_id='' or 1=1 # limit 5;"
在sql中,#表示注釋,#后面的語句都不會被執行,自然limit也就失效了,所有的數據都會被查出來
sql注入原理:
傳入參數中'' or 1=1# 被當作sql語句執行了,or 后面 1=1使條件永遠為真,且# 將limit進行注釋,我們當前表就被脫褲了
預防:
不要手動進行拼接sql語句,execute() 提供了自動拼接功能,並進行了sql注入防范機制
替換為:
proj_id = "'' or 1=1 #"
sql = "SELECT * FROM oss2_base_test.auto_task where proj_id=%s limit 5;"
cursor.execute(sql,(proj_id,))