您的应用程序容易受到严重类安全问题SQL injection的影响。见http://bobby-tables.com/。
当然,O'Brian
会导致错误,但');DROP SCHEMA public;--
怎么办?或者');DELETE FROM users;--
?第一个应该不起作用,因为你的应用程序应该是从来没有作为超级用户或拥有这些表的用户运行,但很少有应用程序设计人员努力实际执行此操作,并且经常运行生产中的特权用户。第二将在大多数应用程序中工作;详情请参阅帖子末尾。
最简单和最好的预防措施是在客户端库中使用参数化语句*。对于Delpi见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文字时,它才能安全地完成,它不仅在每一端都引用了引号,还处理了其他转义,引用加倍等。这是最后的手段;它的强烈最好使用参数化语句。
下面是我上面给出的示例的扩展。假设你正在做的用户名的用户,其中“弗雷德”是由客户端的例子用户名输入的非常普通的插入:
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
中的所有行 - 然后是不执行任何操作的注释。啪。有你的数据。
*参数statemments有时错误地称为准备语句。这是不正确的,因为准备好的语句不一定是参数化的,并且参数化语句不一定准备好。由于许多语言的数据库接口没有提供使用参数化语句而不使用预处理语句的方式,所以引起了混淆。
您可以使用'QuotedStr'函数(尝试sql注入...) – kobik