正确插入表名
Posted
技术标签:
【中文标题】正确插入表名【英文标题】:Proper insertion of table name 【发布时间】:2016-10-07 18:52:03 【问题描述】:如果可以动态确定名称并且仍然可以防止SQL注入攻击,如何正确提供表名?我正在使用node-postgres。
例如:
以下工作,但我认为不安全:
dbclient.query("INSERT INTO " + table_name + " VALUES ($1, $2, $3)", [value_a, value_b, value_c])`
我想要的等效(但不起作用)是:
dbclient.query("INSERT INTO $1 VALUES ($2, $3, $4)", [table_name, value_a, value_b, value_c])`
【问题讨论】:
根据github.com/brianc/node-postgres/issues/1426,在postgres中是不可能的 【参考方案1】:如果表名使用正则表达式某些其他验证逻辑,您可以手动检查有效性。我可能会使用包含允许的表名的字典。
var tables = users:'users', boats:'boats';
table_name = tables[table_name];
if (! table_name) throw new Error();
dbclient.query("INSERT INTO " + table_name + " VALUES ($1, $2, $3)", [value_a, value_b, value_c])
如果您计划生成大量动态 sql,请使用查询构建器,例如 http://knexjs.org/
【讨论】:
我建议您改用table_name = tables.hasOwnProperty(table_name) ? tables[table_name] : null
- 没有用户可以提供的 hasOwnProperty
检查,例如 table_name = 'toString'
,这会导致意外错误。【参考方案2】:
有一个哈希let tables = tableName1: 'table_name1', tableName2: 'table_name2'...
然后
//assuming you receive t as table name input
if(tables[t])
//build SQL query with tables[t] as the table name
else
//throw error about non-existing table
这样,您可以控制数据库中的实际表名。
另外,不要忘记清除所有输入 - 这些值可能包含注入。
【讨论】:
注入攻击对于这种现有的哈希查找会是什么样子?【参考方案3】:任何好的库都应该为 SQL 名称提供适当的转义,包括:
架构名称 表名 列名例如,在pg-promise 中,您可以这样使用它:
db.query("INSERT INTO $1~ VALUES ($2, $3, $4)", [table_name, value_a, value_b, value_c])
即您可以通过在变量后面附加~
来正确转义您的表名,从而使其免受 SQL 注入的影响。
来自here,库执行的表名的简单转义:
return '"' + name.replace(/"/g, '""') + '"';
另见:SQL Names
【讨论】:
【参考方案4】:您可以使用pg-escape
npm 模块中的escape
函数来引用表名等标识符:
只使用转义函数:
escape("INSERT INTO %I VALUES (%L, %L, %L)", table_name, value_a, value_b, value_c);
结合节点postgres:
dbclient.query(escape("INSERT INTO %I VALUES ($2, $3, $4)", table_name), [value_a, value_b, value_c]);
【讨论】:
以上是关于正确插入表名的主要内容,如果未能解决你的问题,请参考以下文章