Delphi – 防止SQL注入
我需要保护一个应用程序免受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'; 此代码是安全的,因为您正在使用参数。 不安全 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'; 在一个(子)查询中不能有两个位置 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |