node-postgres 准备好的语句 - sql 注入

问题描述 投票:0回答: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));
            }
        });

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

node.js postgresql node-postgres
1个回答
1
投票
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;' } ]

并且不会试图掉落任何东西。

© www.soinside.com 2019 - 2024. All rights reserved.