在 node-oracledb 中防止 SQL 注入
Preventing SQL Injection in node-oracledb
node-oracledb 是否转义/清理查询?它通过绑定参数化查询:
connection.execute(
"INSERT INTO countries VALUES (:country_id, :country_name)",
[90, "Tonga"],
function(err, result)
{
if (err)
console.error(err.message);
else
console.log("Rows inserted " + result.rowsAffected);
});
我查看了文档并快速浏览了源代码,但它没有说明或表明它逃避了查询。
如果没有,我正在考虑在传递给 connection.execute
方法之前对用户输入和查询使用 node-mysql as well as copious predicates 的组合。
驱动程序不执行转义,数据库执行,但仅当您使用绑定变量而不是字符串连接时。
您展示的示例是正确且安全的。
这是一个如何以错误的方式进行操作的示例,它会让您面临 SQL 注入:
connection.execute(
"INSERT INTO countries VALUES (" + countryId + ",'" + countryName + "')",
function(err, result)
{
if (err)
console.error(err.message);
else
console.log("Rows inserted " + result.rowsAffected);
});
补充一下 Dan 刚才所说的,(或多或少) 正确的 方式是什么:
SQL 查询字符串现在如下所示:
'INSERT INTO countries VALUES(?,?)'
(注意!问号 不是 引号!)
这个SQL指定要插入的两个值是"parameters."所以具体的值必须是"bound to"这两个参数, 每次执行语句时。
SQL 引擎将直接 从绑定到它们的任何数据源检索每个参数的值,"this time." 因此,regardless of "what (text) they happen to contain," SQL 绝不会认为他们是"part of the SQL statement, itself."
(因此,如果您偶然发现 countries
table 中的一列或另一列包含:"foo; drop table countries"
,毫无疑问它们 会,你会知道... ;-) 确切地 做什么 与那些 ["nice try, Loser!" ...] 行。)
编辑: 正如克里斯托弗·琼斯在对此 post 的回复中友善地指出的那样,Oracle 使用不同的语法来识别参数。然而,基本的 idea 保持不变:呈现给引擎的“SQL 查询”包含要求必须提供的输入值的规范 在运行时, 每次执行语句。这些值完全独立于 SQL 语句本身,永远不会被误解为它的一部分。使用您正在使用的 SQL 引擎所要求的语法。
node-oracledb 是否转义/清理查询?它通过绑定参数化查询:
connection.execute(
"INSERT INTO countries VALUES (:country_id, :country_name)",
[90, "Tonga"],
function(err, result)
{
if (err)
console.error(err.message);
else
console.log("Rows inserted " + result.rowsAffected);
});
我查看了文档并快速浏览了源代码,但它没有说明或表明它逃避了查询。
如果没有,我正在考虑在传递给 connection.execute
方法之前对用户输入和查询使用 node-mysql as well as copious predicates 的组合。
驱动程序不执行转义,数据库执行,但仅当您使用绑定变量而不是字符串连接时。
您展示的示例是正确且安全的。
这是一个如何以错误的方式进行操作的示例,它会让您面临 SQL 注入:
connection.execute(
"INSERT INTO countries VALUES (" + countryId + ",'" + countryName + "')",
function(err, result)
{
if (err)
console.error(err.message);
else
console.log("Rows inserted " + result.rowsAffected);
});
补充一下 Dan 刚才所说的,(或多或少) 正确的 方式是什么:
SQL 查询字符串现在如下所示:
'INSERT INTO countries VALUES(?,?)'
(注意!问号 不是 引号!)
这个SQL指定要插入的两个值是"parameters."所以具体的值必须是"bound to"这两个参数, 每次执行语句时。
SQL 引擎将直接 从绑定到它们的任何数据源检索每个参数的值,"this time." 因此,regardless of "what (text) they happen to contain," SQL 绝不会认为他们是"part of the SQL statement, itself."
(因此,如果您偶然发现 countries
table 中的一列或另一列包含:"foo; drop table countries"
,毫无疑问它们 会,你会知道... ;-) 确切地 做什么 与那些 ["nice try, Loser!" ...] 行。)
编辑: 正如克里斯托弗·琼斯在对此 post 的回复中友善地指出的那样,Oracle 使用不同的语法来识别参数。然而,基本的 idea 保持不变:呈现给引擎的“SQL 查询”包含要求必须提供的输入值的规范 在运行时, 每次执行语句。这些值完全独立于 SQL 语句本身,永远不会被误解为它的一部分。使用您正在使用的 SQL 引擎所要求的语法。