簡體   English   中英

Python字符串格式-字符串替換后的百分比符號

[英]Python String formatting - percentage symbol after string substituion

我試圖通過提供從這樣的方法中獲取的參數來格式化python中的SQL查詢

query = "select * from employees where employee_name like '%s%'" % (name)

運行此代碼時,出現以下錯誤(python 2.6)

ValueError: unsupported format character ''' (0x27) at index 886

我也在命令行中嘗試了一下以找出問題所在

>>> print "hello '%s'" % ('world')
hello 'world'
>>> print "hello '%s\%'" % ('world')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
>>> print "hello '%s%'" % ('world')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
>>> 

當我不立即在單引號內添加%時,%s可以工作,但是即使在轉義后再添加%時,它也會中斷。 是否有補救措施,否則我無法在SQL查詢中替換變量。

這就是SQL注入漏洞的產生方式。 SQL注入將使入侵者可以讀取私有數據,甚至可以修改數據。 永遠不要將原始字符串傳遞到SQL查詢中,除非您確保它沒有特殊字符,例如'%\\ 實際上,最好使用經過良好測試的函數來為您執行此操作。

您會認為:

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不是一個好主意。

有關安全格式化的一些信息,您可以閱讀sql-injection標簽下的堆棧溢出問題,例如防止python中的SQL注入 每個數據庫系統都提供自己的存儲過程接口,請使用它。

雖然您的問題通常是詢問使用python格式化字符串的正確方法,但是對於您的特定用例(這是一個sql查詢),您應該確保正確地轉義了字符串。

這對於(1)停止sql注入攻擊很重要,並且(2)當變量字符串中帶有引號時也很有用。

例如,對於名稱為O'Conner任何人, 您當前的查詢都會出錯

相反,請利用您的庫的參數化方法進行查詢。

您沒有說要使用哪個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)

(當您向cursor.execute提供params參數時,它在后台使用MySQLdb.escape_string 。它還會處理帶引號的換行。請注意,案例1中的%s 不是典型的Python%s,與案例2相反-閱讀以上鏈接中的文檔以了解更多信息。)

嘗試

query = "select * from employees where employee_name like '%{}%'".format(name)

如果您使用的是python 3.6,則也可以使用f-string,如下所示

query = f"select * from employees where employee_name like '%{name}%'"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM