3 回答

TA貢獻1831條經(jīng)驗 獲得超9個贊
這就是 SQL 注入漏洞的誕生方式。SQL 注入會讓入侵者讀取私有數(shù)據(jù),甚至可能修改數(shù)據(jù)。永遠不要通過原始字符串轉(zhuǎn)換成SQL查詢,除非你已經(jīng)確定它有沒有特殊字符,例如',%和\。實際上,最好使用經(jīng)過良好測試的函數(shù)來為您執(zhí)行此操作。
你會認為:
query = "select * from employees where employee_name like '%s%%'" % (name)
# (two `%%` at the end)
解決了你的問題,但如果不知何故name == "%' or '' like '" (或類似的東西),那么查詢突然變成:
"select * from employees where employee_name like '%' or '' like '%'"
這將匹配所有員工。更糟糕的是,即使name = ''在你的情況下也是一場噩夢。首先,我認為like在此類查詢中使用不是一個好主意。
有關(guān)安全格式化的一些信息,您可以閱讀sql-injection標簽下的堆棧溢出問題,例如防止python中的SQL注入。每個數(shù)據(jù)庫系統(tǒng)都提供自己的存儲過程接口,請使用它。

TA貢獻1871條經(jīng)驗 獲得超13個贊
雖然您的問題通常是詢問在python中格式化字符串的正確方法,但是對于您的特定用例(這是一個sql查詢),您應(yīng)該確保正確地轉(zhuǎn)義了字符串。
這對于 (1) 停止 sql 注入攻擊很重要,并且 (2) 當您的變量字符串中有引號時它也很有幫助。
例如,對于名稱為的任何人,您當前的查詢都會出錯O'Conner。
相反,請使用庫的參數(shù)化方法進行查詢。
您沒有說要使用哪個sql庫,因此我將通過MySQLdb給出一個示例。
1) 基本示例(沒有 '%' 通配符):
name = "O'Conner"
query = (
"SELECT *"
" FROM employees"
" WHERE employee_name = %s" # notice the lack of quotes around %s
)
params = (name,)
cursor.execute(query, params)
2)由于您使用的是通配符,因此您需要更加明確:
query = (
"SELECT *"
" FROM employees"
" WHERE employee_name LIKE '{}%'" # must specify the quotes
"".format(
MySQLdb.escape_string(name).replace('%', '\\%').replace('_', '\\_')
)
)
cursor.execute(query)
(當您提供的params參數(shù)時cursor.execute,它MySQLdb.escape_string在幕后使用。它還會處理帶引號的包裝。請注意,案例1中的%s不是典型的python%s,而案例2則相反-請閱讀上面的鏈接了解更多信息。)
添加回答
舉報