在Java中,如果不使用setString()或setInt()等方法,直接将用户输入附加到SQL查询中,但使用PreparedStatement执行查询,是否仍然被视为SQL注入?
我们可以认为这是SQL注入吗?
是的。在解析 SQL 字符串之前将不受信任的输入连接或插入到 SQL 字符串中就是 SQL 注入。
这有助于理解为什么经常提到准备好的语句来防御 SQL 注入。
SQL注入的问题在于你将一些内容与你的SQL查询字符串结合起来,然后提交要解析和执行的字符串。如果内容更改了查询的 SQL 语法,则会导致查询执行您不希望执行的操作。
使用准备好的语句可以将解析 SQL 的步骤与查询的执行分开。一旦在准备步骤中解析了查询,则使用
setString()
或 setInt()
添加的内容就不可能更改查询的语法。查询已经被数据库引擎解析,参数只能被视为标量值,而不是其他 SQL 语法。
换句话说,
setString()
与字符串连接不同。它将在解析查询之后将字符串内容添加到查询中。因此,添加包含会导致不同查询逻辑的字符的内容是安全的。
如果在准备语句之前将 SQL 字符串与不受信任的内容连接起来,这并没有帮助。准备好的语句不会赋予任何将不安全查询变成安全查询的“祝福”。
它们仅让您有机会在
准备好查询之后组合参数。是的,确实仍然容易受到 SQL 注入攻击。
PreparedStatement
参数化查询
。为了通过 JDBC 使用参数化查询,您需要一个
PreparedStatement
。但仅使用 PreparedStatement
并不自动意味着您正在使用参数化查询。
PreparedStatement
不会阻止您将用户输入添加到查询字符串中。为了防止 SQL 注入,您需要将所有用户输入作为参数
传递。这将是一个 SQL 注入,因为自动将值解释为 sql 代码。