为了账号安全,请及时绑定邮箱和手机立即绑定

Python字符串格式-字符串替换后的百分比符号

Python字符串格式-字符串替换后的百分比符号

蓝山帝景 2021-05-30 14:29:28
我试图通过提供从这样的方法中获取的参数来在 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 查询中替换变量。
查看完整描述

3 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

这就是 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注入。每个数据库系统都提供自己的存储过程接口,请使用它。


查看完整回答
反对 回复 2021-06-01
?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

虽然您的问题通常是询问在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)

(当您提供的params参数时cursor.execute,它MySQLdb.escape_string在幕后使用。它还会处理带引号的包装。请注意,案例1中的%s不是典型的python%s,而案例2则相反-请阅读上面的链接了解更多信息。)


查看完整回答
反对 回复 2021-06-01
  • 3 回答
  • 0 关注
  • 203 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信