如何在SQL查询中转义特殊字符,如",以避免注入攻击。

5
使用delphi 2010,我想知道是否有一种方法可以转义以下字符串,以使其免受SQL注入攻击的影响:

我的字符串:

    SQLQuery1.SQL.Text := 'SELECT * FROM registered WHERE email="'+
      email+'" and login_pass="'+password+'"';

如何重写此字符串,以使其更加安全,当有人在我的TEdit框中键入“”作为他的电子邮件或密码时!

13
请使用 SQL 参数 :) - Petar Minchev
请不要在问题标题中放置标签信息。这就是标签的作用,而在标题中重复会使标题变得更长且更难阅读。谢谢。 :) - Ken White
3个回答

14

使用参数,让数据库驱动程序处理这些内容。

SQLQuery1.SQL.Text := 'SELECT * FROM registered WHERE email= :email'+
  ' and login_pass = :password';
SQLQuery1.ParamByName('email').AsString := EMail;
SQLQuery1.ParamByName('password').AsString := Password;

这段代码不起作用。EDatabase错误(操作不支持)。 - Rafik Bari
3
这段代码完全正常,我已经在每天运行的大量代码中使用它。你使用的是什么数据库? 有哪些数据库组件?(顺便说一句,在发布 SQL 问题时应始终提及数据库引擎,因为它们之间的语法和功能不同。) - Ken White
0x0005 操作不支持 - Rafik Bari
2
@Rafik: 再次问一遍,你在使用什么数据库和组件?(如果你有注意到我上一个评论的话,我已经问过了。) - Ken White

0

将 ' 替换为 '' 的基本操作应确保您不会在文本字段中受到注入攻击。

作为经验法则,请确保您添加到数据库中的所有输入都符合您预期的模式。 对于电子邮件地址、邮政编码和密码,您可以定义一个简单的正则表达式来验证其有效性。

请记住,数字字段也可能被注入攻击,因此也应进行验证。


-1
如果由于某种原因您无法使用参数,您可以使用以下函数:
USES SysUtils;

FUNCTION QuotedStr(CONST S : STRING) : STRING;
  BEGIN
    Result:='"'+ReplaceStr(S,'"','""')+'"'
  END;

然后

SQLQuery1.SQL.Text := 'SELECT * FROM registered WHERE email='+
  QuotedStr(email)+' and login_pass='+QuotedStr(password);

(这假设您的数据库提供程序使用双引号来分隔带引号的字符串,并且在带引号的字符串中连续出现两个双引号实际上是一个双引号,即一个双引号)。


2
-1. 这并不能防止 SQL 注入(甚至使其更加困难)。此外,QuotedStr 已经在 RTL 中(在 SysUtils 中)。 - Ken White
如果您的数据库使用单引号(例如SQL Server),请使用QuotedStr(http://docwiki.embarcadero.com/VCL/en/SysUtils.QuotedStr)或AnsiQuotedStr(http://docwiki.embarcadero.com/VCL/en/SysUtils.AnsiQuotedStr)(或始终使用设置为提供程序语法的变量的AnsiQuotedStr)。 - Gerry Coll
2
@KenWhite:只是出于好奇,这个代码怎么不会防止SQL注入? - HeartWare
2
那不是一个有效的例子,因为我的代码将是<TestQry:='SELECT * FROM FOO WHERE User='+QuotedStr(Memo1.Text);>(减去尖括号),这将导致SQL语句<SELECT * FROM FOO WHERE User=""""";DELETE * FROM foo;SELECT * FROM foo WHERE user = ""JONES"""> (减去尖括号)这不会做任何坏事。它只会搜索名为<"";DELETE * FROM foo;SELECT * FROM foo WHERE user = "JONES">(没有尖括号)的用户。 - HeartWare
1
@HeartWare,我同意你的观点。有时候人们会过度设计并使用包装器,而实际解决方案非常简单。如果预期输入是字符串,则转义引号将防止 SQL 注入! - Uri Goren
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接