sql - 对于 FreePascal 和 Delphi,是否有用于清理 PostgreSQL 或 SQL 查询参数的库?

标签 sql delphi postgresql sql-injection freepascal

当我尝试使用包含撇号的值执行下面的 PostgreSQL 查询时,我遇到了我的第一个 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)]));

在上面的查询中,SQuote 是一个将字符串用单引号引起来的函数。是否有一些标准库可以为 Lazarus/FreePascal 或 Delphi 清理 SQL 查询参数?

最佳答案

您的应用程序容易受到名为 SQL injection 的一类严重安全问题的攻击。 .参见 http://bobby-tables.com/ .

当然,O'Brian导致错误,但是 ');DROP SCHEMA public;-- 呢? ?或者 ');DELETE FROM users;-- ?第一个不应该工作,因为您的应用程序永远不应该以 super 用户或拥有表的用户身份运行,但很少有应用程序设计者努力真正做到这一点,并且经常在生产中运行特权用户。第二个适用于大多数应用程序;详情见文末。

最简单和最好的预防措施是在您的客户端库中使用参数化语句*。参见 this example对于德尔皮:

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,最后一次编写 Pascal 代码是在 1995 年;我只是引用给出的示例)。

您目前正在做的是参数的字符串插值。这是非常危险的。只有当你有一个强大的引用 SQL 文字 的函数时,它才能安全地完成,这个函数不仅在每一端加上引号,而且还处理其他转义、引用加倍等。它是最后手段的方法; 强烈最好使用参数化语句。


这是我上面给出的示例的扩展。假设您正在通过用户名对用户进行完全普通的插入,其中“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 中的所有行- 然后是一个什么都不做的评论。扑通一声。你的数据不见了。


* 参数化语句有时被错误地称为准备好的语句。这是不正确的,因为准备好的语句不一定是参数化的,参数化的语句也不一定是准备好的。之所以会产生混淆,是因为许多语言的数据库接口(interface)不提供在不使用预准备语句的情况下使用参数化语句的方法。

关于sql - 对于 FreePascal 和 Delphi,是否有用于清理 PostgreSQL 或 SQL 查询参数的库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13171048/

相关文章:

delphi - IExplorer.exe 的 ShellExecute 路径

sql - Postgresql 中的字符串字段长度

sql - 复制 SQL Server 2008 数据库并重命名

delphi - 如何将任务的执行情况报告给下一个流程消息?

delphi - 调用外部函数给出不满足的前向或外部声明

java - 在 JPA 存储库中调用 (Postgres) 函数

postgresql - 使用 Prisma 的嵌套创建查询返回未定义

sql - 如何为每个外键选择有限数量的行? (以及如何指定关系)

BIGINT 列上的 SQL Like/Contains

postgresql - postgresql sql shell命令中不同服务器之间的切换