加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi – 防止SQL注入

发布时间:2020-12-15 10:19:51 所属栏目:大数据 来源:网络整理
导读:我需要保护一个应用程序免受SQL注入。应用程序正在连接到Oracle,使用ADO,并搜索用户名和密码以进行身份??验证。 从我到现在为止,最好的方法是使用参数,而不是将整个SQL分配为字符串。这样的东西: query.SQL.Text := 'select * from table_name where na
我需要保护一个应用程序免受SQL注入。应用程序正在连接到Oracle,使用ADO,并搜索用户名和密码以进行身份??验证。

从我到现在为止,最好的方法是使用参数,而不是将整个SQL分配为字符串。这样的东西:

query.SQL.Text := 'select * from table_name where name=:Name and id=:ID'; 
query.Prepare; 
query.ParamByName( 'Name' ).AsString := name; 
query.ParamByName( 'ID' ).AsInteger := id; 
query.Open;

此外,我想验证来自用户的输入,并删除SQL关键字,如删除,插入,选择等…任何输入字符不同于正常的ASCII字母和数字将被删除。

这将确保我最低的安全级别?

我不想使用除Delphi 7标准和Jedi之外的任何其他组件。

解决方法

安全
query.SQL.Text := 'select * from table_name where name=:Name';

此代码是安全的,因为您正在使用参数。
参数总是安全的从SQL注入。

不安全

var Username: string;
...
query.SQL.Text := 'select * from table_name where name='+ UserName;

是不安全的,因为用户名可以是名称;删除table_name;
导致执行以下查询。

select * from table_name where name=name; Drop table_name;

也不安全

var Username: string;
...
query.SQL.Text := 'select * from table_name where name='''+ UserName+'''';

因为如果用户名是’或(1 = 1);删除表名 – –
它将导致以下查询:

select * from table_name where name='' or (1=1); Drop Table_name; -- '

但是这段代码是安全的

var id: integer;
...
query.SQL.Text := 'select * from table_name where id='+IntToStr(id);

因为IntToStr()只接受整数,所以没有SQL代码可以注入到查询字符串这种方式,只有数字(这是你想要的,因此允许)

但我想做的东西,不能用参数

参数只能用于值。它们不能替换字段名称或表名称。
所以如果你想执行这个查询

query:= 'SELECT * FROM :dynamic_table '; {doesn't work}
query:= 'SELECT * FROM '+tableName;      {works,but is unsafe}

第一个查询失败,因为您不能使用表或字段名称的参数。
第二个查询是不安全的,但是这是可以做到的唯一的方法。
如何保持安全?

您必须检查字符串tablename批准的名称列表。

Const
  ApprovedTables: array[0..1] of string = ('table1','table2');

procedure DoQuery(tablename: string);
var
  i: integer;
  Approved: boolean;
  query: string;
begin
  Approved:= false;
  for i:= lo(ApprovedTables) to hi(ApprovedTables) do begin
    Approved:= Approved or (lowercase(tablename) = ApprovedTables[i]);
  end; {for i}
  if not Approved then exit;
  query:= 'SELECT * FROM '+tablename;
  ...

这是唯一的办法做到这一点,我知道。

BTW您的原始代码有错误:

query.SQL.Text := 'select * from table_name where name=:Name where id=:ID';

应该

query.SQL.Text := 'select * from table_name where name=:Name and id=:ID';

在一个(子)查询中不能有两个位置

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读