【发布时间】:2011-05-11 13:00:32
【问题描述】:
在postgres中使用CREATE SCHEMA schema_name时,如果需要用户输入,如何防止schema_name参数的SQL注入?
schema_name 不能是引用值,因此例如 ActiveRecord::Base.sanitize() 将不起作用。 (如果您使用导轨)。
【问题讨论】:
标签: postgresql schema sql-injection
在postgres中使用CREATE SCHEMA schema_name时,如果需要用户输入,如何防止schema_name参数的SQL注入?
schema_name 不能是引用值,因此例如 ActiveRecord::Base.sanitize() 将不起作用。 (如果您使用导轨)。
【问题讨论】:
标签: postgresql schema sql-injection
允许用户创建模式(通常是做 DDL)是相当不寻常的(甚至是可怕的)。你确定要这样做吗?
在任何情况下,您都可以做通常的事情:清理您的输入(我猜如果您允许用户创建 schames,至少您可以限制允许的名称 - 例如只有字母数字等),和/或使用准备好的语句,绑定架构名称(这取决于您的语言/环境)。
【讨论】:
我知道这可能不是您正在寻找的答案,但如果您的设计让用户决定您的架构名称,但您不信任您的用户,那么您确实需要重新设计。让您的用户决定模式名称类似于要求用户决定类和函数名称。
如果您真的非常想这样做,我会使用正则表达式将其限制为仅 16 个字母数字字符,以字母字符开头,强制小写 (/^[a-z][a-z0- 9]{1,15}$/)。您还需要明确过滤掉“public”作为架构名称、information_schema(如果您也允许使用下划线)和其他内置架构名称。
再次,我愿意打赌你真的不想这样做,并且有更好的方法来解决你的根本问题。
【讨论】:
用户永远不应该拥有 DDL 权限,他们不需要它,这给了他们太多权力。
您可以使用带有 quote_ident 的 SQL 函数来创建架构并避免 SQL 注入:
CREATE OR REPLACE FUNCTION new_schema(IN _schemaname TEXT)
RETURNS bool
LANGUAGE plpgsql
AS
$$
BEGIN;
EXECUTE 'CREATE SCHEMA ' || quote_ident(_schemaname);
RETURN true;
END;
$$
SECURITY DEFINER;
-- test:
SELECT new_schema('Frank; drop database template1');
【讨论】: