如何使用 Snowflake python 连接器在查询中安全地插入(sql 注入)标识符?

ece*_*ulm 5 snowflake-cloud-data-platform

为了避免 SQL 注入攻击,我想使用绑定变量/查询参数,但这些似乎不适用于标识符(例如表名或用户名)

import snowflake.connector
import os
def myfunc(username):
    with snowflake.connector.connect(user=os.environ['SF_USER'], password=os.environ['SF_PASSWORD'], account=os.environ['SF_ACCOUNT']) as ctx:
        cs = ctx.cursor().execute('''SHOW GRANTS TO USER %s''', (username))
        print(cs.rowcount)
        rint(cs.fetchone())
myfunc('TEST2') # Raises a ProgrammingError: 001003 (42000): SQL compilation error: syntax error line1 at position 20 unexpected ''TEST2''
Run Code Online (Sandbox Code Playgroud)

我想在上面的测试中TEST2是作为文字'TEST2`` and not as an identifier“TEST2”插入的。

如果我不能为此使用绑定变量/查询参数,我想我需要自己构造字符串 f'''SHOW GRANTS TO USER {username}'''但是在字符串插值之前我必须有哪些选项来清理输入?

顺便说一句,我知道而不是SHOW GRANTS TO USER "<username>"我可以使用select * from "SNOWFLAKE"."ACCOUNT_USAGE"."GRANTS_TO_USERS" where deleted_on is null and grantee_name = '<username2'which 来避免问题,因为在后一个查询中,用户名被用作文字而不是标识符。但我发现它SNOWFLAKE.ACCOUNT_USAGE.GRANTS_TO_USERS是滞后的(不会立即显示最新的更改,在我的情况下延迟了 20 分钟以上)。

那么我可以使用什么来清理用作标识符的值以防止 SQL 注入攻击呢?

ece*_*ulm 7

正如@SimeonPilgrim 在评论中指出的那样, 有一个函数IDENTIFIER可用于将绑定变量转换为标识符。

所以而不是... TO USER %s使用... TO USER IDENTIFIER(%s)

import snowflake.connector
import os
def myfunc(username):
    with snowflake.connector.connect(user=os.environ['SF_USER'], password=os.environ['SF_PASSWORD'], account=os.environ['SF_ACCOUNT']) as ctx:
        cs = ctx.cursor().execute('''SHOW GRANTS TO USER IDENTIFIER(%s)''', (username))
        print(cs.rowcount)
        rint(cs.fetchone())
myfunc('TEST2') # Works!
Run Code Online (Sandbox Code Playgroud)