3

参数用于保护您免受恶意用户输入的影响。

但是如果参数需要一个字符串,是否可以编写将被解释为 sql 的输入,以便恶意用户可以使用诸如 'DROP'、'TRUNCATE' 之类的东西......?

asp、asp.net、java等中的参数保护有区别吗?


另请参阅:参数真的足以防止 SQL 注入吗?

4

6 回答 6

12

如果参数化查询是幕后的字符串,则参数化查询通常会引用该参数,以便正常的 SQL 运算符不会被解释为这样。这意味着即使用户输入了潜在的恶意数据,它也会被简单地视为字符串输入,而不是解释为 SQL 运算符/命令。

它在各种框架中的实现方式可能存在技术差异,但基本思想(和结果)是相同的。

于 2009-01-15T12:35:01.933 回答
9

你需要小心你的定义。“参数”可能意味着很多东西;例如,存储过程的参数本身并不能保护您。以 Java 为例:

sql = "exec proc_SearchForUser '" + userNameToSearch + "'";

不比生的好或差

sql = "SELECT * FROM Users WHERE userName = '" + userNameToSearch + "'";

并且同样容易受到用户名的影响

';DROP TABLE users;--

另一方面,参数化查询是安全的。他们可能看起来像

PreparedStatement statement = con.prepareStatement("SELECT * FROM Users WHERE userName = ?");

或者确实

PreparedStatement statement = con.prepareStatement("exec proc_SearchForUser ?");

这是安全的原因是因为当您填写值时......使用,比如说,

statement.setString(1, userName);

那么字符串——即使是像“';DROP TABLE users;--”这样的字符串——将被数据库引擎正确转义并呈现无害。

仍然有可能把它搞砸——例如,如果你的存储过程只是在内部构建一个 SQL 字符串并执行它,信任输入——但是带有参数的准备好的语句意味着没有未转义的数据将完全到达数据库服务器切断该攻击向量。

于 2009-01-15T12:40:22.373 回答
3

不会。任何 SQL 数据库中的任何语言都可能发生 SQL 注入攻击。您所指的攻击类型是程序员在其源代码中使用动态 SQL,例如“USER_NAME = sName”,并且用户可以为用户名输入无限的文本,以便他们可以附加注释,然后键入任何新的 SQL 语句,例如“删除”、“截断”等。

于 2009-01-15T12:35:06.723 回答
3

您通过 BindWhatever() 调用作为参数输入的任何内容都不能作为 SQL 执行。

在绑定 ht 变量数据之前,SQL 已经被解析和评估,因此这些数据根本不可能被误认为是 SQL。

当然,当数据库将忠实地存储并可能在其他人的浏览器上执行时,仍然有人可以向您传递一些 JavaScript!

因此,您仍然需要摆脱输入(或至少转义)任何 ({[]})\ 类型的字符;

于 2009-01-15T12:37:52.287 回答
1

不作为参数。SQL 注入依赖于将恶意代码连接到 SQL 字符串中,然后从该字符串执行 SQL 语句。无论内容如何,​​准备好的语句都带有参数。使用准备好的语句,SQL 语句本身的实际文本永远不会改变。

于 2009-01-15T12:33:02.297 回答
1

唯一的风险是如果您exec对参数化字符串执行 an 。

在所有其他情况下,参数化查询是安全的。

于 2009-01-15T12:33:53.167 回答