【问题标题】:Peewee: how to pass raw SQL query parameter without apostrophesPeewee:如何传递不带撇号的原始 SQL 查询参数
【发布时间】:2022-10-06 01:33:39
【问题描述】:

使用 Python 和 Peewee,我想创建一个将 SQL 视图名称作为参数并返回其结果的函数。为了避免任何不必要的 SQL 注入,我想将视图名称作为 SQL 查询参数传递:

def run_view_query(view_name: str):
    query = BaseModel.raw(\"SELECT * FROM %s\", view_name)
    return query

问题是 Peewee 自动在关键字周围添加撇号,所以我收到以下错误:

peewee.ProgrammingError: syntax error at or near \"\'vw_all_users\"
LINE 1: SELECT * FROM \'vw_all_users\'

我知道我可以像这样使用 python f-string 来做到这一点:

query = BaseModel.raw(f\"SELECT * FROM {view_name}\")

但随后我必须对可能的 SQL 注入威胁进行一些正则表达式验证。有没有更好的解决方案?

  • 您替换的概念是防止 sql 注入,但它仅适用于值,因为 sql 必须事先知道所有表和列,因此永远不会替换表或列名。所以在运行代码之前创建一个白名单并将其与表名进行比较

标签: python sql postgresql peewee flask-peewee


【解决方案1】:

为什么要参数化视图名称?大概您提前知道要从哪个视图中选择——尽管如果这是容易受到不受信任的输入的影响,那么您需要自己对其进行清理。

Peewee 将所有用户提供的参数转发给驱动程序,驱动程序负责将它们转义或使用安全的 API 来避免注入。表名/视图名不能以这种方式参数化。

【讨论】:

    【解决方案2】:

    PeeWee 使用类来表示表和视图。因此,您可以在 Python 端使用 if/elif/else:

    def run_view_query(view_name: str):
      if view_name == "Foo":
        return Foo.select()
      elif view_name == "Bar":
        return Bar.select()
      else:
        return SomeDefault.select()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-18
      • 1970-01-01
      • 1970-01-01
      • 2020-05-02
      • 2017-08-07
      • 2017-07-27
      相关资源
      最近更新 更多