javascript - 如何编写 SQL 查询以安全地将记录插入可变表名?

标签 javascript sql node.js postgresql sql-injection

我有一个向表中插入记录的函数。表名需要作为函数的参数,列名是动态获取的。为了防止 SQL 注入(inject),我想使用 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 替换对值非常有效,但它不能用于表或列标识符。

来自PostgreSQL documention

Arguments to the SQL function are referenced in the function body using the syntax $n: $1 refers to the first argument, $2 to the second, and so on. If an argument is of a composite type, then the dot notation, e.g., $1.name, can be used to access attributes of the argument. The arguments can only be used as data values, not as identifiers



将此与以下代码进行比较,该代码有效但似乎对 SQL 注入(inject)几乎没有提供保护。

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

function insert(tableName, val1, val2) {

    let values = ['col1', 'col2', val1, val2]
    let qry =   `INSERT INTO ${tableName} (${values[0]}, ${values[1]})
                VALUES ($3, $4)
                RETURNING id;`


    return db.query(qry, values);
}


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

我正在运行 Node 9.4 和 PostgreSQL 10

最佳答案

如果你有以下参数:

  • table - 表名
  • columns - 列名数组或具有属性的对象
  • values - 对应列值的数组

然后是pg-promise中最简单的方法语法如下:

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});
}

参见 SQL Names , CSV Filter .

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

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

Under SQL Names, the first example shows how a column name can be inserted dynamically. Is this insertion something that is done by your library, or does the replacement happen on the Postgres side?

PostgreSQL 服务器不允许动态 SQL 名称,pg-promise在内部实现它,提供安全转义以防止 SQL 注入(inject)。

关于javascript - 如何编写 SQL 查询以安全地将记录插入可变表名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48719334/

相关文章:

javascript - 在 Chart.js 中将标签颜色更改为特定值

javascript - Touchend 不起作用,即使在调用 e.preventDefault() 之后也是如此

javascript - Internet Explorer 9 上的 Javascript 未处理字符 NULL (ASCII 0)

java - getValueAt() 方法返回 null

node.js - Sails V0.10-rc7 通过 Socket.IO 使用 REST 蓝图从数据库获取记录

javascript - Upstart 说我的脚本正在运行,但 API 在我重新启动进程之前不会返回数据

node.js - Express:不发送对请求的响应

javascript - php/html显示从特定数据开始的自动周计数器

sql - 选择具有不同条件的多列

SQL - 使用 "min"和 groupby 进行过滤