防止SQL注入的正确方法?

Right Approach for preventing SQL Injection?

提问人:Jagan 提问时间:9/12/2023 更新时间:10/11/2023 访问量:65

问:

假设我有以下代码,其中 studentId 来自用户输入,

const sql  = 'select Name from student where Id = ' + studentId;
connection.exec(sql)

上面的代码肯定容易发生SQL注入。我想知道以下两个选项是否解决了SQL注入攻击,并且是相同的。

选项 1.使用 PL/SQL 变量声明并将用户输入与模板绑定

const sql  = `DECLARE @Id=${studentId}; select Name from student where Id = @Id;`;
connection.exec(sql)

选项 2.使用库提供的参数选项

const sql  = 'select Name from student where Id = @Id;';
parameters.add({name: Id, value: studentId})
connection.exec(sql,parameters)
节点.js SQL注入

评论

2赞 8ns 9/12/2023
我会说选项 2 是最好的。在选项 1 中,您只是使用不同的方式连接字符串,但您仍在做的是字符串连接。
0赞 Jorge Montejo 9/12/2023
你为数据库使用什么库?
0赞 Jagan 9/12/2023
@JorgeMontejo - 用于连接到 MS SQL Server 的 npmjs.com/package/tedious。我发布的语法只是为了提供概述,而不是确切的语法。
0赞 jQueeny 9/12/2023
始终使用预准备语句。npm mysql2 pg mssql 上的所有主要 SQL 驱动程序都提供预处理语句作为其库的一部分。按照他们的文档,您将安全无虞。
0赞 Jorge Montejo 9/12/2023
@jQueeny他正在使用的库也提供了它,因此他仍然可以使用该库而不是切换到其他库。

答:

0赞 Jorge Montejo 9/12/2023 #1

最好的办法是从对象连接中使用函数 execute,发送 Request 和参数。

function prepareSQL() {
  const sql = `INSERT INTO USERS VALUES (@val1, @val2)`;

  const request = new Request(sql, (err, rowCount) => {
    if (err) {
      throw err;
    }

  });

  // Must add parameters
  request.addParameter('val1', TYPES.Int);
  request.addParameter('val2', TYPES.Int);

  request.on('prepared', () => {
    console.log('request prepared');
    executePreparedSQL(request);
  });

  connection.prepare(request);
}

function executePreparedSQL(request) {
  connection.execute(request, { val1: 1, val2: 2 });

  request.on('requestCompleted', () => {
    console.log('DONE!');
    connection.close();
  });
}

您可以在此处查看示例。

有关函数执行的详细信息,请参阅官方文档

-1赞 Gokul Raam 10/11/2023 #2

将 studentId 的值视为类似于以下内容:

studentId = “1;拖放表some_table”

案例 1 容易受到 SQL 注入的影响,因为它也只是字符串连接的一种形式。在这种情况下,生成的 sql 查询将是

声明 @Id=1;放置表 some_table;选择学生姓名,其中 id = @Id;

因此,案例 2 始终是首选,因为它使用 bind 参数