在SQL中“转义查询值”如何安全? (或者为什么这很危险?)[SQL注入]

时间:2019-04-29 01:44:06

标签: mysql sql node.js sql-injection

我正在W3schools上使用SQL示例关注Node.js。 here

它说下面的代码防止SQL注入。

var adr = 'Mountain 21';
var sql = 'SELECT * FROM customers WHERE address = ' + mysql.escape(adr);
con.query(sql, function (err, result) {
if (err) throw err;
console.log(result);
});
  

当查询值是用户提供的变量时,应转义这些值。这是为了防止SQL注入,SQL注入是破坏或滥用数据库的常见网络黑客技术。

这就是解释。

我想了解这是多么安全。 (这如何防止SQL注入)。

此外,以下代码有何危险?
    var sql = 'SELECT * FROM customers WHERE address = "Mountain 21"';

2 个答案:

答案 0 :(得分:5)

如果注入的值(即“ Mountain 21”)来自不受控制的外部源,则未经保护的字符串串联生成SQL语句是危险的。例如,它是由用户输入的。

请考虑以下纯字符串连接:

var adr = <something accepted from an external source>
var sql = `SELECT * FROM customers WHERE address = "${adr}"`;

然后考虑如果用户在文本字段中输入以下内容,将会发生什么情况:

Mountain 21"; delete all from customers; //

查询将变为:     选择*来自客户的地址=“ Mountain 21”;从客户中删除所有内容; //“

如果您执行该操作,最终可能会导致表中没有客户。

我个人不熟悉node.js mysql.escape函数的操作,但是通常这些函数会“转义”特殊字符,因此会失去其“特殊性”。例如,它可能在\前面放一个\。删除它作为语句分隔符的重要性。

转义函数通常会执行的另一个更常见的示例是将一段文本(例如“ O'Brien”转换为“ O” Brien”)(两个单引号是在SQL中指定单引号的方式文字字串)。使用“ O'Brien”名称的查询将如下所示:

select *
from customers
where name = 'O''Brien';

几乎可以肯定,mySql.escape函数将提供“ O'Brien”到“ O''Brien”的必要转换,以便可以在SQL查询中正确运行。没有转义,查询的最后一行将显示为:

where name = 'O'Brien';

这将导致语法错误。

FWIW,最安全的方法是使用?查询中用户提供的值(例如地址)中的占位符。这有点麻烦,因为您需要准备查询,提供所有值然后执行它。但是,好处是,这(应该是?)完全不受大多数​​(即使不是全部)“注射攻击”的影响。

按照您的示例进行参数化查询的基本流程是(在Java伪代码中-因为我不关心node.js在该领域的功能)

val sql = "SELECT * FROM customers WHERE address = ?";
val preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString (1, adr);
val resultSet = preparedStatement.executeQuery();

大多数(如果不是全部)数据库都支持参数化查询,大多数语言都公开了此功能,但并非所有语言都公开了此功能(或至少不容易实现)。同样,我不确定node.js。

希望对您有帮助。

答案 1 :(得分:0)

var adr = 'Mountain 21';
var sql = `SELECT * FROM customers WHERE address = "${mysql.escape(adr)}"`;
con.query(sql, function (err, result) {
if (err) throw err;
console.log(result);
});

var sql = 'SELECT * FROM customers WHERE address = Mountain 21';

var sql = 'SELECT * FROM customers WHERE address = "Mountain 21"';

https://stackoverflow.com/a/33679883/11343720

Grave accent更好quotedouble quote