是否有一个库,用于对PostgreSQL或SQL的查询参数,通常用于Freepascal和Delphi



当我试图用包含撇号的值执行以下值时,我被咬伤了我的第一个SQL逃脱错误(早就应该)。O'Brien,使用Freepascal和Lazarus

SQL.Add(format('select * from zones where upper(zn_name) >=  %s and upper(zn_name) < %s order by zn_name',[sQuote(zoneMin), sQuote(zoneMax)]));

在上面的查询中,蹲下是一个将字符串包裹在单引号中的函数。是否有一些标准库来消毒lazarus/freepascal或Delphi的SQL查询参数?

您的应用程序容易受到严重类别的安全问题,称为SQL注入。请参阅http://bobby-tables.com/。

当然,O'Brian会导致错误,但是');DROP SCHEMA public;--呢?还是');DELETE FROM users;--?第一个不应该使用,因为您的应用程序应该从事超级用户或拥有桌子的用户,但是很少有应用程序设计师努力实际做到这一点,并且经常在生产中运行特权用户。第二个将在大多数应用程序中工作;有关详细信息,请参见帖子的结尾。

最简单,最佳的预防措施是在客户库中使用参数化语句*。请参阅此示例的Delpi:

To use a prepared statement, do something like this:
query.SQL.Text := 'update people set name=:Name where id=:ID';
query.Prepare;
query.ParamByName( 'Name' ).AsString := name;
query.ParamByName( 'ID' ).AsInteger := id;
query.ExecSQL;

(我从未使用过Delphi,最后在1995年写了Pascal代码;我只是引用了给出的示例)。

您当前正在做的是参数的字符串插值。这是非常危险的。仅当您具有强大的函数以引用sql literals 时,它才能安全完成,它不仅在两端都引用了引号,还可以处理其他逃生,报价加倍等。这是最后的方法;强烈使用参数化语句。

是强烈的

这是我上面给出的示例的扩展。假设您正在使用用户名对用户进行完全普通的插入,其中" fred"是客户端的示例用户名输入:

INSERT INTO users ( user_name ) VALUES ('Fred');

现在有些不愉快的人发送用户名');DELETE FROM users;--。突然您的应用程序正在运行:

INSERT INTO users ( user_name ) VALUES ('');DELETE FROM users;--');

扩展时是:

INSERT INTO users ( user_name ) VALUES ('');
DELETE FROM users;
--');

或换句话说,插入一个空字符串的插入物(尽管它们可以轻松地放置一个完美有效的用户名),然后使用DELETE FROM users;语句 - 删除users中的所有行 - 然后是评论,无用。Splat。有您的数据。


*有时将参数化的陈述错误地称为准备的语句。这是不正确的,因为准备好的语句不一定是参数化的,并且不一定准备参数化的语句。由于许多语言的数据库界面没有提供参数化语句的方法,因此出现了混乱。

最新更新