在插入硬编码和可变值的混合时避免SQL注入?

在插入硬编码和可变值的混合时避免SQL注入?,sql,postgresql,pg-promise,Sql,Postgresql,Pg Promise,我正在用编写数据库查询。我的桌子是这样的: Table "public.setting" │ user_id │ integer │ not null │ visualisation_id │ integer │ not null │ name │ character varying │ not null

我正在用编写数据库查询。我的桌子是这样的:

                                    Table "public.setting"
│ user_id          │ integer           │ not null                
│ visualisation_id │ integer           │ not null  
│ name             │ character varying │ not null                                  

                                    Table "public.visualisation"
│ visualisation_id │ integer           │ not null                
│ template_id      │ integer           │ not null  
我想在设置中插入一些值-三个是硬编码的,一个我需要从可视化中查找

以下语句满足我的需要,但必须易受SQL注入的攻击:

var q = "INSERT INTO setting (user_id, visualisation_id, template_id) (" +
        "SELECT $1, $2, template_id, $3 FROM visualisation WHERE id = $2)";
conn.query(q, [2, 54, 'foo']).then(data => {
    console.log(data); 
});
我知道我应该使用,但如果我尝试按如下方式使用它们,我会得到TypeError:无效的sql名称:2:

我想这并不奇怪,因为它将2放在双引号中,所以SQL认为它是一个列名

如果我尝试重写查询以使用值,我还会得到一个语法错误:

var q = "INSERT INTO setting (user_id, visualisation_id, template_id) VALUES (" +
        "$1, $2, SELECT template_id FROM visualisation WHERE id = $2, $3)";

在避免SQL注入风险的同时,插入硬编码和可变值的最佳方法是什么?

您的查询很好。我想您也知道值占位符$X参数和SQL名称,但您有点困惑

在查询中,仅为占位符赋值。数据库驱动程序将为您处理它们,提供正确的转义和变量替换

报告说:

参数的数据类型未指定或声明为 未知,从参数所在的上下文推断类型 如果可能,请使用

我找不到一个声明默认类型的源,但我认为INSERT语句提供了足够的上下文来标识真正的类型


另一方面,在以友好方式构建查询时,必须使用。例如,您有变量列或表名。它们必须通过$1~或$1:name样式参数插入,以保护您免受注入攻击。

要将查询用作值,请将其放入括号中,如子查询$1、$2,从Visualization中选择template_id,其中id=$2、$3我认为@VaoTsun在这里是正确的。SQL名称在这里没有任何作用,因为您没有使用动态列名。谢谢。在第一个示例中,用户不能提供一些SQL来代替$1并可能实现SQL注入,因为内部查询使用动态列名吗?我正在检查现有代码的漏洞。@Richard我不这么认为,因为$1代表一个简单的值。如果您传递任何字符串,它将作为字符串正确转义,不可能进行任何注入。@Richard您需要在那里使用SQL名称,在一个简单的选择中。但您的示例是一个使用SELECT的INSERT,这是一个不同的故事。
var q = "INSERT INTO setting (user_id, visualisation_id, template_id) VALUES (" +
        "$1, $2, SELECT template_id FROM visualisation WHERE id = $2, $3)";