为什么python的数据库语句要用参数化构造的方式

以下是一个python的数据库插入语句

self.cur.execute('''
    INSERT INTO books (
        url, title, product_type, price_excl_tax, price_incl_tax, availability, num_reviews, rating, category, describe
    ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
''', (
    item['url'], item['title'], item['product_type'], item['price_excl_tax'], item['price_incl_tax'], item['availability'], item['num_reviews'], item['rating'], item['category'], item['describe']
))

为什么不使用似乎更简单的f-string

self.cur.execute(f'''
    INSERT INTO books (
        url, title, product_type, price_excl_tax, price_incl_tax, availability, num_reviews, rating, category, describe
    ) VALUES ({item['url']}, {item['title']}, ... )
''')

答案是为了防止SQL注入攻击,第二中方式如果遇到这样发语句

{
  "url": "' OR 1=1 --",
  "title": "Malicious Title",
  // 其他字段省略,保持正常值
}

那么sql语句就换变成

INSERT INTO books (
  url, title, product_type, price_excl_tax, price_incl_tax, availability, num_reviews, rating, category, describe
) VALUES (
  ''' OR 1=1 --', 'Malicious Title', ... 
)

单引号 ' 结束了原本的字符串字面值,并通过注释符号 -- 忽略了后面的语句。这里的 '' OR 1=1 是一个永远为真的布尔表达式,通过这种方式可以绕过url这个字段的有效性检查。
而前一种方式会检测输如字段的合规性,避免这种危险。

posted @ 2024-04-16 20:32  ling_2945  阅读(15)  评论(0)    收藏  举报