91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

pymysql解決sql注入問題的示例分析

發布時間:2021-05-20 10:28:33 來源:億速云 閱讀:216 作者:小新 欄目:數據庫

這篇文章將為大家詳細講解有關pymysql解決sql注入問題的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

1. SQL 注入

SQL 注入是非常常見的一種網絡攻擊方式,主要是通過參數來讓 mysql 執行 sql 語句時進行預期之外的操作。

即:因為傳入的參數改變SQL的語義,變成了其他命令,從而操作了數據庫。

產生原因:SQL語句使用了動態拼接的方式。

例如,下面這段代碼通過獲取用戶信息來校驗用戶權限:

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('登陸成功')

但是,如果傳入參數是:

input['id'] = '2 or 1=1'

你會發現,用戶能夠直接登錄到系統中,因為原本 sql 語句的判斷條件被 or 短路成為了永遠正確的語句。
這里僅僅是舉一個例子,事實上,sql 注入的方式還有很多種,這里不深入介紹了。

總之,只要是通過用戶輸入數據來拼接 sql 語句,就必須在第一時間考慮如何避免 SQL 注入問題。

那么,如何防止 SQL 注入呢?

2. 預防 SQL 注入 – pymysql 參數化語句

pymysql 的 execute 支持參數化 sql,通過占位符 %s 配合參數就可以實現 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('登陸成功')

這樣參數化的方式,讓 mysql 通過預處理的方式避免了 sql 注入的存在。

需要注意的是,不要因為參數是其他類型而換掉 %s,pymysql 的占位符并不是 python 的通用占位符。

同時,也不要因為參數是 string 就在 %s 兩邊加引號,mysql 會自動去處理。

3. 預防 SQL 注入 – mysql 存儲過程

數據庫存儲過程是 mysql 的一種高級用法,但是一般來說,并不建議使用數據庫的存儲過程。

主要原因是:

  • 存儲過程的語法與普通 SQL 語句語法相差太大,增加維護成本

  • 存儲過程在各數據庫間不通用且差別較大,給數據庫的移植和擴展帶來困難

  • 編寫困難,數據庫腳本語言使用起來還是很不方便的,包括很多數據結構的缺失,讓很多事情做起來很困難

  • 調試困難,雖然有一些功能強大的 IDE 提供了數據庫存儲過程的調試功能,但是通常你需要同時在數據庫層面上和業務中同時進行調試,兩處調試極為不便

  • 業務耦合,編寫存儲過程通常是需要在其中放入部分業務邏輯,這使得業務分散在數據層,業務層與數據層的耦合對于項目維護和擴展都會帶來極大地不便。

但是,雖然不建議使用存儲過程,但是畢竟可以依賴他實現各種跨語言的 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()

關于“pymysql解決sql注入問題的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

西林县| 阜宁县| 五河县| 探索| 皮山县| 和田县| 华宁县| 崇阳县| 调兵山市| 西和县| 定南县| 新乐市| 元阳县| 阿鲁科尔沁旗| 北辰区| 肇庆市| 英超| 和硕县| 榆社县| 玉溪市| 青铜峡市| 利辛县| 武城县| 鹤峰县| 靖西县| 三亚市| 颍上县| 吉安市| 彰武县| 蚌埠市| 达拉特旗| 准格尔旗| 襄垣县| 屯昌县| 栾川县| 平阳县| 凉城县| 阿克陶县| 屏山县| 宣城市| 张家口市|