Odoo E8103:SQL 注入风险。如果可以,请使用参数

Odoo E8103: SQL injection risk. Use parameters if you can

我正在使用 odoo pylint 并遇到此消息 'Odoo E8103: SQL injection risk. Use parameters if you can'。它指的是以下示例 SQL 查询行模式:

 self.env.cr.execute("""SELECT sq_qty , prod_id ...
        FROM st
        LEFT JOIN prod
        ON prod.id = st.prod_id
        WHERE %s
        GROUP BY prod_id, loc_id, ..."""% domain, args)

并且根据 OCA No SQL Injection,最好的安全方法是永远,永远不要使用 Python 字符串连接 (+) 或字符串参数插值 (%) 将变量传递给 SQL查询字符串。

我尝试用“,”替换“%”,并用 () 将域和参数括起来:GROUP BY prod_id, loc_id, ...""", (domain, args) ), 它通过了检查,但不确定这是否是正确的方法。

是放置 skip check 更好还是按照 pylint 的建议修改它,如果修改更好,正确的处理方法是什么?

编辑:我将 sql 查询语句分隔为一个变量

query = """SELECT sq_qty , prod_id ...
        FROM st
        LEFT JOIN prod
        ON prod.id = st.prod_id
        WHERE """
query += domain + """ GROUP BY prod_id, loc_id, ..."""
self.env.cr.execute(query, args)

使用 Classic approach since I'm using dynamic WHERE clause with domain and following OCA description,实现了无错误地通过 lint 和 运行

您已正确更改它。如果您不完全确定其背后的原因,请永远不要忽略该 lint 消息。

OCA description已经有正确答案了,为什么要避免这样的代码。

Care must be taken not to introduce SQL injections vulnerabilities when using manual SQL queries. The vulnerability is present when user input is either incorrectly filtered or badly quoted, allowing an attacker to introduce undesirable clauses to a SQL query (such as circumventing filters or executing UPDATE or DELETE commands).

The best way to be safe is to never, NEVER use Python string concatenation (+) or string parameters interpolation (%) to pass variables to a SQL query string.

The second reason, which is almost as important, is that it is the job of the database abstraction layer (psycopg2) to decide how to format query parameters, not your job! For example psycopg2 knows that when you pass a list of values it needs to format them as a comma-separated list, enclosed in parentheses!

甚至提到了 xkcd 的老漫画“Bobby tables”;-)