在PostgreSQL中执行批插入时如何防止SQL注入?

在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 我想提供更多的上下文。我将要使

我想在一个批处理操作中插入多达100个项目。我是这样做的:

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表呢?我不是又回到了向表中插入记录的问题了吗?