Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何编写将记录安全插入变量表名的SQL查询?_Javascript_Sql_Node.js_Postgresql_Sql Injection - Fatal编程技术网

Javascript 如何编写将记录安全插入变量表名的SQL查询?

Javascript 如何编写将记录安全插入变量表名的SQL查询?,javascript,sql,node.js,postgresql,sql-injection,Javascript,Sql,Node.js,Postgresql,Sql Injection,我有一个将记录插入表的函数。表的名称需要是函数的参数,列名是动态获取的。为了防止SQL注入,我想使用PostgreSQL的参数化查询。大概是这样的: function insert(tableName, val1, val2) { let qry = `INSERT INTO $1 ($2, $3) VALUES ($4, $5) RETURNING id;` let values = [tableName,

我有一个将记录插入表的函数。表的名称需要是函数的参数,列名是动态获取的。为了防止SQL注入,我想使用PostgreSQL的参数化查询。大概是这样的:

function insert(tableName, val1, val2) {
    let qry =   `INSERT INTO $1 ($2, $3)
                VALUES ($4, $5)
                RETURNING id;`

    let values = [tableName, 'col1', 'col2', val1, val2]

    return db.query(qry, values);
}
虽然
$n
替换对值非常有效,但不能用于表或列标识符

SQL函数的参数在函数体中使用语法$n引用:$1引用第一个参数,$2引用第二个参数,依此类推。如果参数是复合类型,则可以使用点表示法(例如$1.name)访问参数的属性。参数只能用作数据值,不能用作标识符



将此代码与下面的代码进行比较,下面的代码可以工作,但似乎对SQL注入没有什么保护

(注意使用ECMA6
${}
字符串替换代替参数替换)


有没有一种方法可以允许参数化查询来缓解这种情况?我希望在PostgreSQL或节点的Postgres库中内置一些东西,但我会接受任何可靠的答案


我正在运行Node 9.4和PostgreSQL 10,一个选项是在继续之前使用参数从可用表列表中检查表名


我不确定是否有更简单的方法来传输变量,但如果您将值放入一个临时表中,并调用从临时表中获取值的过程,将这些值插入到动态选择的表中,您应该是相当安全的。

我建议在这种情况下使用对象关系映射(ORM),这是我个人的建议,也许对你有帮助

这是一个图书馆链接 你可以 使用

objective.js构建在一个名为knex的SQL查询生成器上。

这样就可以编写一个干净的语法了

这里有一个非常简单的例子

//
person
person
模型的一个实例

const movie = await person
  .$relatedQuery('movies')
  .insert({name: 'The room', awesomeness: 9001});

console.log('best movie ever was added');

insert into "Movie" ("name") values ('The room')

如果您具有以下参数:

  • 表格
    -表格名称
  • -列名数组或具有属性的对象
  • -对应列值的数组
语法中最简单的方法如下:

function insert(table, columns, values) {
    const query = 'INSERT INTO ${table:name} (${columns:name}) VALUES(${values:csv})'; 
    return db.query(query, {table, columns, values});
}
或更简短的语法:

function insert(table, columns, values) {
    const query = 'INSERT INTO ${table~} (${columns~}) VALUES(${values:csv})'; 
    return db.query(query, {table, columns, values});
}

从7.5.0版开始,动态对象变得更加简单:

function insert(table, obj) {
    const query = 'INSERT INTO ${table:name} (${obj:name}) VALUES(${obj:csv})'; 
    return db.query(query, {table, obj});
}
在下,第一个示例显示了如何动态插入列名。这种插入是由您的库完成的,还是在Postgres端进行替换


PostgreSQL server不允许动态SQL名称,在内部实现,提供安全转义以防止SQL注入。

您使用什么驱动程序执行SQL命令?@AbderrahmaneTAHRIJOUTI我使用的是节点postgres()。我没有遇到任何替代方案。您可以使用,及其动态生成架构/表/列名;)如果感兴趣,我可以将其作为答案发布;)@vitaly-t谢谢你。我看了一下这个库,我认为它比只使用pg更好。但是我有点困惑我将如何使用它来解决上面的问题。在下,第一个示例显示了如何动态插入列名。这种插入是由您的库完成的,还是在Postgres端进行替换?不管怎样,如果你想写下来作为答案,我会接受的。谢谢。我不太确定我是否遵循(SQL新手)。我的想法是用一个查询生成一个全新的表,然后如果该表成功生成,将插入的行复制到实际的表中吗?这是否也适用于动态生成的列名?否,第一个过程将val1和val2插入临时表,并检查表名是否在和表列表中。第二个过程从临时表中获取这些值,然后插入到变量表中,然后从临时表中删除它们。我喜欢这个想法,因为我认为它对于我想要做的事情非常有效。但是,您提供的链接已失效。引用的帐户没有GitHub页面。@此处是链接
function insert(table, obj) {
    const query = 'INSERT INTO ${table:name} (${obj:name}) VALUES(${obj:csv})'; 
    return db.query(query, {table, obj});
}