1. SQL 注入
SQL 注入是非常常見的一種網(wǎng)絡攻擊方式,主要是通過參數(shù)來讓 mysql 執(zhí)行 sql 語句時進行預期之外的操作。
即:因為傳入的參數(shù)改變SQL的語義,變成了其他命令,從而操作了數(shù)據(jù)庫。
產(chǎn)生原因:SQL語句使用了動態(tài)拼接的方式。
例如,下面這段代碼通過獲取用戶信息來校驗用戶權限:
import pymysql sql = 'SELECT count(*) as count FROM user WHERE id = ' + str(input['id']) + ' AND password = "' + input['password'] + '"' cursor = dbclient.cursor(pymysql.cursors.DictCursor) cursor.execute(sql) count = cursor.fetchone() if count is not None and count['count'] > 0: print('登陸成功')
但是,如果傳入?yún)?shù)是:
input['id'] = '2 or 1=1'
你會發(fā)現(xiàn),用戶能夠直接登錄到系統(tǒng)中,因為原本 sql 語句的判斷條件被 or 短路成為了永遠正確的語句。
這里僅僅是舉一個例子,事實上,sql 注入的方式還有很多種,這里不深入介紹了。
總之,只要是通過用戶輸入數(shù)據(jù)來拼接 sql 語句,就必須在第一時間考慮如何避免 SQL 注入問題。
那么,如何防止 SQL 注入呢?
2. 預防 SQL 注入 – pymysql 參數(shù)化語句
pymysql 的 execute 支持參數(shù)化 sql,通過占位符 %s 配合參數(shù)就可以實現(xiàn) sql 注入問題的避免。
import pymysql sql = 'SELECT count(*) as count FROM user WHERE id = %s AND password = %s' valus = [input['id'], input['password']] cursor = dbclient.cursor(pymysql.cursors.DictCursor) cursor.execute(sql, values) count = cursor.fetchone() if count is not None and count['count'] > 0: print('登陸成功')
這樣參數(shù)化的方式,讓 mysql 通過預處理的方式避免了 sql 注入的存在。
需要注意的是,不要因為參數(shù)是其他類型而換掉 %s,pymysql 的占位符并不是 python 的通用占位符。
同時,也不要因為參數(shù)是 string 就在 %s 兩邊加引號,mysql 會自動去處理。
3. 預防 SQL 注入 – mysql 存儲過程
數(shù)據(jù)庫存儲過程是 mysql 的一種高級用法,但是一般來說,并不建議使用數(shù)據(jù)庫的存儲過程。
主要原因是:
但是,雖然不建議使用存儲過程,但是畢竟可以依賴他實現(xiàn)各種跨語言的 sql 注入預防,在復雜的場景下還是有其使用價值的。(以后需要用再去詳細學,這里只作簡單介紹)
3.1. 存儲過程編寫
delimiter \DROP PROCEDURE IF EXISTS proc_sql \CREATE PROCEDURE proc_sql ( in nid1 INT, in nid2 INT, in callsql VARCHAR(255) ) BEGIN set @nid1 = nid1; set @nid2 = nid2; set @callsql = callsql; PREPARE myprod FROM @callsql; -- PREPARE prod FROM 'select * from tb2 where nid>? and nid?'; 傳入的值為字符串,?為占位符 -- 用@p1,和@p2填充占位符 EXECUTE myprod USING @nid1,@nid2; DEALLOCATE prepare myprod; END\delimiter ;
3.2. pymsql 中調用
import pymysql cursor = conn.cursor() mysql="SELECT * FROM user where nid > ? and nid ?" cursor.callproc('proc_sql', args=(11, 15, mysql)) rows = cursor.fetchall() conn.commit()
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
標簽:景德鎮(zhèn) 荊門 江蘇 瀘州 淮安 威海 那曲 柳州
巨人網(wǎng)絡通訊聲明:本文標題《pymysql如何解決sql注入問題深入講解》,本文關鍵詞 pymysql,如何,解決,sql,注入,;如發(fā)現(xiàn)本文內容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權與本站無關。