使用 table 名称的 Python 防止 BigQuery 中的 SQL 注入
Prevent SQL Injection in BigQuery with Python for table name
我有一个 Airflow DAG,它接受用户对 table
的参数。
然后我在 SQL 语句中使用这个值并在 BigQuery 中执行它。我担心自己会受到 SQL 注射。
代码如下:
sql = f"""
CREATE OR REPLACE TABLE {PROJECT}.{dataset}.{table} PARTITION BY DATE(start_time) as (
//OTHER CODE
)
"""
client = bigquery.Client()
query_job = client.query(sql)
dataset
和 table
都通过气流通过,但我担心有人会通过类似的东西:random_table; truncate other_tbl; --
作为 table
参数。
我担心上面的代码会创建一个名为 random_table
的 table,然后截断现有的 table。
是否有更安全的方法来处理这些通过参数传递的内容?
我研究了 BigQuery 中的参数化查询,但这些查询不适用于 table 个名称。
您可能应该调查 sanitization/validation 一般的用户输入。这是在 将输入传递给 BQ 查询之前完成的。
使用 Python,您可以在用户输入中查找恶意字符串 - 例如您的示例中的 truncate
- 或者使用正则表达式过滤例如包含 --
的输入。这些只是一些简单的例子。我建议您对该主题进行更多研究;您还会在 SE 上找到很多关于该主题的问题。
您必须创建一个 table 名称验证器。我认为您可以通过在 table 名称字符串的开头和结尾仅使用 backticks
--> ` 来安全地进行验证。这不是 100% 的解决方案,但它适用于我尝试的一些测试场景。它应该像这样工作:
# validate should look for ` at the beginning and end of your tablename
table_name = validate(f"`{project}.{dataset}.{table}`")
sql = f"""
CREATE OR REPLACE TABLE {table_name} PARTITION BY DATE(start_time) as (
//OTHER CODE
)
"""
...
注意:我建议您在medium站点上查看以下post以查看bigquery sql injection。
我查看了关于 Running parameterized queries 的官方文档,遗憾的是它只涵盖了变量的参数化而不是 tables 或查询的其他字符串部分。
最后一点,我建议针对这种特定情况为 BigQuery 打开 feature request。
我有一个 Airflow DAG,它接受用户对 table
的参数。
然后我在 SQL 语句中使用这个值并在 BigQuery 中执行它。我担心自己会受到 SQL 注射。
代码如下:
sql = f"""
CREATE OR REPLACE TABLE {PROJECT}.{dataset}.{table} PARTITION BY DATE(start_time) as (
//OTHER CODE
)
"""
client = bigquery.Client()
query_job = client.query(sql)
dataset
和 table
都通过气流通过,但我担心有人会通过类似的东西:random_table; truncate other_tbl; --
作为 table
参数。
我担心上面的代码会创建一个名为 random_table
的 table,然后截断现有的 table。
是否有更安全的方法来处理这些通过参数传递的内容?
我研究了 BigQuery 中的参数化查询,但这些查询不适用于 table 个名称。
您可能应该调查 sanitization/validation 一般的用户输入。这是在 将输入传递给 BQ 查询之前完成的。
使用 Python,您可以在用户输入中查找恶意字符串 - 例如您的示例中的 truncate
- 或者使用正则表达式过滤例如包含 --
的输入。这些只是一些简单的例子。我建议您对该主题进行更多研究;您还会在 SE 上找到很多关于该主题的问题。
您必须创建一个 table 名称验证器。我认为您可以通过在 table 名称字符串的开头和结尾仅使用 backticks
--> ` 来安全地进行验证。这不是 100% 的解决方案,但它适用于我尝试的一些测试场景。它应该像这样工作:
# validate should look for ` at the beginning and end of your tablename
table_name = validate(f"`{project}.{dataset}.{table}`")
sql = f"""
CREATE OR REPLACE TABLE {table_name} PARTITION BY DATE(start_time) as (
//OTHER CODE
)
"""
...
注意:我建议您在medium站点上查看以下post以查看bigquery sql injection。
我查看了关于 Running parameterized queries 的官方文档,遗憾的是它只涵盖了变量的参数化而不是 tables 或查询的其他字符串部分。
最后一点,我建议针对这种特定情况为 BigQuery 打开 feature request。