1

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

(上)完美运行。帮助我理解我在这里做错了什么的任何帮助都会很棒。

4

1 回答 1

0
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如果nadlongtable_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)here 被用作lient.query(object QUERY,array VALUES)并且 VALUES 在 QUERY 对象中克服了这种情况,这是你[msg]被“忽略”的......

注意

检查准备好的语句是否对此类 sql 注入进行了修剪是没有意义的,因为此功能的实现是出于对此类注入安全的想法。例如,即使您将使用数据类型 text(以避免类型不匹配)并尝试注入分号和 drop 语句,prepared statement 也会将注入视为文字值,因此是安全的。例如:

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;' } ]

而不是试图丢弃任何东西。

于 2017-10-11T12:30:19.387 回答