我是node-postgres的新手,当我尝试确保我准备好的语句不可能进行sql注入时,无法解决此错误。
这是代码片段
// the prepared statement
var preparedstatement = client.query({
text: "select ST_AsText(ST_Transform(geodata,4326)) from table_name where ST_Contains(ST_GeomFromText($1,4326),table_name.geodata)",
values: ["POINT(Lat Long)"],
name: 'where'
});
// the query
var queryresult = client.query({name: 'where', values: [msg]},["'; DROP TABLE user;"], function(err) {
if (err) {
socket.emit('query error', String(err));
}
});
每当我输入地理数据(作为来自使用 socket.io 的客户端的消息)时,socket.emit 都会返回一个错误,指出
几何图形无效
但是,当我从代码中删除
["'; DROP TABLE user;"],
时,代码工作正常,即
// the query
var queryresult = client.query({name: 'where', values: [msg]}, function(err) {
if (err) {
socket.emit('query error', String(err));
}
});
(上图)效果很好。任何帮助我理解我在这里做错了什么的帮助都会很棒。
var preparedstatement = client.query({
text: "select ST_AsText(ST_Transform(geodata,4326)) from table_name where ST_Contains(ST_GeomFromText($1,4326),table_name.geodata)",
values: ["POINT(Lat Long)"],
name: 'where'
});
SQL 结果类似
prepare "where" as
select ST_AsText(ST_Transform(geodata,4326))
from table_name
where ST_Contains(ST_GeomFromText($1,4326),table_name.geodata);
execute "where" (POINT(Lat Long));
如果
lat
nad long
是 table_name
属性,这可能会起作用
下一个:
var queryresult = client.query({name: 'where', values: [msg]}, function(err) {
if (err) {
socket.emit('query error', String(err));
}
});
是:
execute "where" (msg_value);
如果它们具有兼容的数据类型,这可能会起作用
最后:
var queryresult = client.query({name: 'where', values: [msg]},["'; DROP TABLE user;"], function(err) {
if (err) {
socket.emit('query error', String(err));
}
});
运行 SQL:
execute "where" ('''; DROP TABLE user;');
这会产生错误,因为该文本不是有效的几何图形...
值得注意的是,这里的
lient.query(text QUERY,array VALUES)
被用作 lient.query(object QUERY,array VALUES)
并且 VALUES 在 QUERY 对象中克服了这样的问题,这你的 [msg]
被“忽略”了...
注意
检查准备好的语句是否针对此类 sql 注入进行了修剪是没有意义的,因为此功能是通过对此类注入安全的想法来实现的。例如,即使您使用数据类型文本(以避免类型不匹配)并尝试注入分号和删除语句,准备好的语句也会将注入视为文字值,因此是安全的。例如:
var preparedstatement = client.query({
text: "select $1::text resulting_att",
values: ['some default'],
name: 'ps_name'}
);
var queryresult = client.query({name: 'ps_name'},["'; DROP TABLE user;"], function(err,res) {
console.log(err,res.rows)
client.end()
});
日志:
null [ anonymous { resulting_att: '\'; DROP TABLE user;' } ]
并且不会试图掉落任何东西。