在PostgreSQL中执行批插入时如何防止SQL注入?
我想在一个批处理操作中插入多达100个项目。我是这样做的:在PostgreSQL中执行批插入时如何防止SQL注入?,postgresql,sql-injection,bulkinsert,Postgresql,Sql Injection,Bulkinsert,我想在一个批处理操作中插入多达100个项目。我是这样做的: INSERT INTO MyTable (f1, f2, ..., fk) VALUES (v11, v12, ..., v1k), (v21, v22, ..., v2k), ... (vn1, vn2, ..., vnk) 一切都很好,但我通过按原样连接值来构建这个字符串,这意味着我的代码容易受到SQL注入的攻击 一方面,如何继续使用大容量插入语法,同时又不受SQL注入的影响 编辑1 我想提供更多的上下文。我将要使
INSERT INTO MyTable (f1, f2, ..., fk) VALUES
(v11, v12, ..., v1k),
(v21, v22, ..., v2k),
...
(vn1, vn2, ..., vnk)
一切都很好,但我通过按原样连接值来构建这个字符串,这意味着我的代码容易受到SQL注入的攻击
一方面,如何继续使用大容量插入语法,同时又不受SQL注入的影响
编辑1
我想提供更多的上下文。我将要使用的实际SQL(此时编写代码)具有以下形式:
WITH new_parent AS (
INSERT into parent (g1, g2, ..., gm) VALUES (v1, v2, ..., vm) RETURNING id
) INSERT INTO MyTable (parent_id, f1, f2, ..., fk) VALUES
(new_parent.id, v11, v12, ..., v1k),
(new_parent.id, v21, v22, ..., v2k),
...
(new_parent.id, vn1, vn2, ..., vnk)
如果可能,请使用COPY语句。它速度稍快,所需内存明显减少,而且SQL注入防弹——因为数据使用不同的通道。如果可能的话,使用COPY语句。它速度稍快,所需内存明显减少,而且是SQL注入防弹的—因为数据使用不同的通道。您可以构建一个串联的参数字符串,而不是实际值,然后使用一个数组传递值,该数组按正确的顺序包含所有值。例如:
CREATE TYPE paramValues AS {
"ID" integer,
"V1" text
.
.
.
}
CREATE OR REPLACE FUNCTION bulk(data paramValues[])
RETURNS integer AS
$BODY$
DECLARE
BEGIN
WITH new_parent AS (
INSERT into parent (g1, g2, ..., gm) VALUES (v1, v2, ..., vm) RETURNING id
) INSERT INTO MyTable (parent_id, f1, f2, ..., fk) VALUES
($1, $2, $3, ..., $k),
($k+1, $k+2, $k+3, ..., $k+k),
...
($m, $m+1, $m+2, ..., $m+k);
return 1;
END$BODY$
LANGUAGE 'plpgsql' VOLATILE;
您可以构建一个串联的参数字符串,而不是实际值,然后使用一个数组传递值,该数组按正确的顺序包含所有值。例如:
CREATE TYPE paramValues AS {
"ID" integer,
"V1" text
.
.
.
}
CREATE OR REPLACE FUNCTION bulk(data paramValues[])
RETURNS integer AS
$BODY$
DECLARE
BEGIN
WITH new_parent AS (
INSERT into parent (g1, g2, ..., gm) VALUES (v1, v2, ..., vm) RETURNING id
) INSERT INTO MyTable (parent_id, f1, f2, ..., fk) VALUES
($1, $2, $3, ..., $k),
($k+1, $k+2, $k+3, ..., $k+k),
...
($m, $m+1, $m+2, ..., $m+k);
return 1;
END$BODY$
LANGUAGE 'plpgsql' VOLATILE;
通过转义函数传递值有什么问题?没有它,即使复制命令也会受到\的攻击。实际上,PostgreSQL似乎可以在
PREPARE
语句中处理多达2^15-1个参数,因此我似乎可以用刚刚发现的{vij}
形式的相应命名参数替换$1,$2,
的值集。通过转义函数传递值有什么错?没有它,即使复制命令也会受到\的攻击。实际上,PostgreSQL似乎可以在PREPARE
语句中处理多达2^15-1个参数,因此我似乎可以用刚刚发现的{vij}
形式的相应命名参数替换$1,$2,
。我添加了edit1。副本声明是否仍然相关?您需要使用CTE?为什么不将临时表与COPY一起使用?能否给我一个示例,说明如果使用COPY,我的查询会是什么样子?@mark with COPY,您需要两个步骤-首先,创建临时表,然后用COPY语句填充表。使用COPY语句取决于您的环境。但是如何填充temp表呢?我不是又回到了向表中插入记录的问题了吗?我添加了编辑1。副本声明是否仍然相关?您需要使用CTE?为什么不将临时表与COPY一起使用?能否给我一个示例,说明如果使用COPY,我的查询会是什么样子?@mark with COPY,您需要两个步骤-首先,创建临时表,然后用COPY语句填充表。使用COPY语句取决于您的环境。但是如何填充temp表呢?我不是又回到了向表中插入记录的问题了吗?