'Escaping query values' 在 sql 中如何安全? (或者为什么危险?) [SQL 注射]
How is 'Escaping query values' safe in sql? (Or why is it dangerous?) [SQL injection]
我在 W3schools 上关注 Node.js sql 个例子。 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);
});
When query values are variables provided by the user, you should escape the values.This is to prevent SQL injections, which is a common web hacking technique to destroy or misuse your database.
这就是解释。
我想了解这是如何安全的。 (这如何防止 SQL 注入)。
另外,下面的代码有什么危险?
var sql = 'SELECT * FROM customers WHERE address = "Mountain 21"';
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"';
Grave accent
比较好quote
,double quote
如果注入的值(即 "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; //
查询将变为:
SELECT * 来自客户,地址 = "Mountain 21";从客户中删除所有内容; //
如果你 运行 这样做,你的 table 中可能会没有客户。
我个人不熟悉 node.js mysql.escape 函数的操作,但通常这类函数 "escape" 特殊字符,因此它们会丢失 "special-ness"。例如,它可能会在 ; 前面放一个 \。删除它作为语句分隔符的重要性。
转义函数通常会做的另一个更常见的例子是将一段文本如 "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,最安全的方法是使用 ?查询用户提供的值(例如地址)中的占位符。这有点麻烦,因为您需要准备查询、提供所有值然后执行它。然而,好处是它(应该?)完全不受大多数(如果不是全部)形式的 "injection attack".
的影响。
根据您的示例,参数化查询的基本流程是(在 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.
希望对您有所帮助。
我在 W3schools 上关注 Node.js sql 个例子。 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);
});
When query values are variables provided by the user, you should escape the values.This is to prevent SQL injections, which is a common web hacking technique to destroy or misuse your database.
这就是解释。
我想了解这是如何安全的。 (这如何防止 SQL 注入)。
另外,下面的代码有什么危险?
var sql = 'SELECT * FROM customers WHERE address = "Mountain 21"';
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"';
Grave accent
比较好quote
,double quote
如果注入的值(即 "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; //
查询将变为: SELECT * 来自客户,地址 = "Mountain 21";从客户中删除所有内容; //
如果你 运行 这样做,你的 table 中可能会没有客户。
我个人不熟悉 node.js mysql.escape 函数的操作,但通常这类函数 "escape" 特殊字符,因此它们会丢失 "special-ness"。例如,它可能会在 ; 前面放一个 \。删除它作为语句分隔符的重要性。
转义函数通常会做的另一个更常见的例子是将一段文本如 "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,最安全的方法是使用 ?查询用户提供的值(例如地址)中的占位符。这有点麻烦,因为您需要准备查询、提供所有值然后执行它。然而,好处是它(应该?)完全不受大多数(如果不是全部)形式的 "injection attack".
的影响。根据您的示例,参数化查询的基本流程是(在 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.
希望对您有所帮助。