pymysql 解決 sql 注入問題

2021-08-31 06:57:06 字數 2807 閱讀 4477

sql 注入是非常常見的一種網路攻擊方式,主要是通過引數來讓 mysql 執行 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

notnone

and count[

'count'

]>0:

print

('登陸成功'

)

但是,如果傳入引數是:

input

['id']=

'2 or 1=1'

你會發現,使用者能夠直接登入到系統中,因為原本 sql 語句的判斷條件被 or 短路成為了永遠正確的語句。

這裡僅僅是舉乙個例子,事實上,sql 注入的方式還有很多種,這裡不深入介紹了。

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

那麼,如何防止 sql 注入呢?

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

notnone

and count[

'count'

]>0:

print

('登陸成功'

)

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

需要注意的是,不要因為引數是其他型別而換掉 %s,pymysql 的佔位符並不是 python 的通用佔位符。

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

資料庫儲存過程是 mysql 的一種高階用法,但是一般來說,並不建議使用資料庫的儲存過程。

主要原因是:

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

儲存過程在各資料庫間不通用且差別較大,給資料庫的移植和擴充套件帶來困難

編寫困難,資料庫指令碼語言使用起來還是很不方便的,包括很多資料結構的缺失,讓很多事情做起來很困難

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

業務耦合,編寫儲存過程通常是需要在其中放入部分業務邏輯,這使得業務分散在資料層,業務層與資料層的耦合對於專案維護和擴充套件都會帶來極大地不便

但是,雖然不建議使用儲存過程,但是畢竟可以依賴他實現各種跨語言的 sql 注入預防,在複雜的場景下還是有其使用價值的,這裡僅做一些介紹。

delimiter \drop

procedure

ifexists 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

;

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注入的方法

import pymysql class db object def init self self.conn pymysql.connect host 192.168.0.58 user root password 123456 port 3306 self.cursor self.conn.cur...

sql注入解決

所謂sql注入,就是通過把sql命令插入到web表單遞交或輸入網域名稱或頁面請求的查詢字串,最終達到欺騙伺服器執行惡意的sql命令。我們永遠不要信任使用者的輸入,我們必須認定使用者輸入的資料都是不安全的,我們都需要對使用者輸入的資料進行過濾處理。1.以下例項中,輸入的使用者名稱必須為字母 數字及下劃...

PyMySQL基本使用以及SQL注入問題

目錄又是乙個可以幫助我們實現用 來運算元據庫的模組,安裝,匯入即可 然後匯入即可使用 pymysql基本使用 import pymysql conn pymysql.connect user root password 123 host 127.0.0.1 port 3306,charset utf...