node-postgres准备语句 - sql注入

时间:2014-08-20 16:00:55

标签: node.js postgresql node-postgres

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

(上图)效果很好。帮助我理解我在做错的任何帮助都会很棒。

1 个答案:

答案 0 :(得分: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 nad longtable_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]被“忽略”......

<强> NB

检查准备好的语句是否可以修剪这样的SQL注入是没有意义的,因为这个功能是为了安全进行这样的注入而实现的。例如,即使您将使用数据类型文本(以避免类型不匹配)并尝试注入分号和drop语句,准备好的语句会将注入视为文字值,并且thsus是安全的。例如:

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

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