Sal*_*dor 7 sql delphi sql-injection
我知道sql语句中参数的用法,但只是为了好奇,使用Format函数来防止sql注入而不是使用参数是安全的.
喜欢这个样本
sCustomer : string
begin
AdoSql.CommandText:=Format('Select SUM(value) result from invoices where customer=%s',[QuotedStr(sCustomer)]);
end;
Run Code Online (Sandbox Code Playgroud)
Mas*_*ler 11
这可能对SQL注入是安全的,假设QuotedStr按预期工作并且没有可以破坏它的边缘情况.(这绝不是保证.正如Linas在评论中指出的那样,MySql允许你使用它\'来逃避引号.其他DBMS可能具有相似的功能.具有足够理论知识的攻击者将能够利用它们.)
但是,即使QuotedStr足够好,但出于不同的原因使用参数仍然更好:性能.将参数与查询分开时,最终可能会使用不同的参数多次发送完全相同的查询代码.如果这样做,数据库可以缓存它在计算查询时所做的大量工作,因此您的数据库访问速度会更快.当您将参数混合到查询代码本身时,这不起作用(或至少不行).
每次通过将字符串连接在一起构建SQL字符串时,无论您认为访问这些字符串的安全性如何,都有可能发生注入攻击.众所周知,有人可以在调试器中运行您的应用程序,在结果上设置断点QuotedStr(),并在允许Format()查看之前修改其内容.
使用实际的SQL参数是最安全的方法.它不仅可以避免注入,而且还允许SQL引擎决定如何最好地将参数格式化为自己的需要,这样您就不必担心在自己的代码中格式化值,它适用于强类型语言(如Delphi).更不用说能够提前在服务器端准备SQL语句然后在代码中执行它的性能优势,甚至多次,从而大大减少客户端和服务器之间的流量并提高整体性能.
var
sCustomer : string
begin
AdoSql.CommandText := 'Select SUM(value) result from invoices where customer=:Customer';
AdoSql.Prepared := True;
...
AdoSql.Parameters['Customer'].Value := sCustomer;
AdoSql1.ExecSQL;
...
AdoSql.Parameters['Customer'].Value := sCustomer;
AdoSql1.ExecSQL;
...
AdoSql.Prepared := False;
end;
Run Code Online (Sandbox Code Playgroud)
不,FormatSQL注入没有安全性.在这方面,它与普通的字符串连接没有什么不同.
问题代码中对SQL注入执行任何操作的部分是调用QuotedStr,您可以使用或不使用Format.但它并不像真正的参数化查询那样可靠.
Format在这种情况下,唯一的优点是整个字符串模板在一个地方,所以你不太可能得到间距和标点错误,如果你不得不用连续的+操作构造字符串,那么SQL撇号可以迷失在Delphi撇号中.