python使用pg數據sql注入分析
內容
審計python使用psycopg2庫操作pg數據庫中的sql注入
sql注入出現原因
總結有3個原因
1 對外接口中有不可信的數據輸入
2 未對輸入的數據進行安全性校驗(白名單,轉義等其他限制)
3 操作數據庫時使用函數的方法不對
審計python代碼
直接對查數據庫拼接字符串和查詢方法進行審計
tip1:對輸入數據直接拼接後查詢
def database():
injectdata = "1"
xcmd= "select * from user where id = " + injectdata #psycopg2庫未對數據校驗,傳入什麼參數,execute方法就會執行什麼
conn = psycopg2.connect(database="test", user="post", password=passwd, host=ip, port="5432")
cur = conn.cursor()
cur.execute(xcmd)
res = cur.fetchall()
conn.commit()
conn.close()
拼接注入語法:
1 injectdata = “1 and 1=1” 或者 injectdata = “1 or id =2” #查詢成功
2 injectdata = " 1’ or id =‘2’ " #查詢報錯(有安全校驗)#log(psycopg2.ProgrammingError: unterminated quoted string at or near “’”
3 injectdata = ‘1;select user’ #查詢成功,顯示當前用戶
4 injectdata = ‘1;select pg_sleep(5)’ #查詢成功
說明:"select * from user where id = " + injectdata 這中直接拼接的代碼寫法對sql注入基本沒有安全校驗
tip2:對輸入數據進行格式化後查詢數據庫
def database():
injectdata = "1"
xcmd= "select * from user where id = %s"%injectdata #格式化處理
conn = psycopg2.connect(database="test", user="post", password=passwd, host=ip, port="5432")
cur = conn.cursor()
cur.execute(xcmd)
res = cur.fetchall()
conn.commit()
conn.close()
注入語法驗證:
1 injectdata = “1 and 1=1” 或者 injectdata = “1 or id =2” #查詢成功
2 injectdata = " 1’ " #查詢報錯(有安全校驗)#log(psycopg2.ProgrammingError: unterminated quoted string at or near “’”
3 injectdata = ‘1;select version()’ #查詢成功,有版本號返回
4 injectdata = ‘1;select pg_sleep(5)’ #基於時間盲注查詢成功
說明:"select * from user where id = %s "%injectdata 這種格式化處理傳入數據的寫法與tip1中一樣,未對數據進行安全性校驗
tip3:對輸入數據進行格式化後參數化的調用execute函數
def database():
injectdata = "1"
xcmd= "select * from user where id = %s" #格式化處理
conn = psycopg2.connect(database="test", user="post", password=passwd, host=ip, port="5432")
cur = conn.cursor()
cur.execute(xcmd,injectdata) **#or [injectdata] or (injectdata) ,官網給出安全操作sql的調用方法,用傳參數的方法調用。**
res = cur.fetchall()
conn.commit()
conn.close()
注入語法:
1 injectdata = “1 and 1=1” 或者 injectdata = “1 or id =2” #報錯TypeError: not all arguments converted during string formatting
2 injectdata = " 1’ " # 報錯
3 injectdata = ‘1;select version()’ #報錯
4 injectdata = ‘1;select pg_sleep(5)’ #報錯
python 調用psycopg的sql注入防禦方法:
psycopg2最直接最根本的解決方案是用官網提供的傳參方式操作數據庫。
#the correct conversion (no more SQL injections!) #正確使用(有sql注入防禦)
官網地址:http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries
說明:做python白盒代碼審計時,重點看psycopg庫的使用方法是否是傳參調用的。
ps:本段代碼只是爲了驗證python調用psycopg時sql的相關內容,在實際項目中一般看不到這麼調用的,如果有這麼寫的安全問題還有很多(如:沒有try,沒有數據校驗…)