mysql_real_escape_string 不够好?
因此,即使使用 mysql_real_escape_string 清理数据,也可以使用 %27 进行 SQL 注入
%27) SQL INJECTION HERE %2F*
该怎么办?
编辑示例:
$sql = sprintf("SELECT *, MATCH(post) AGAINST ('%s*' IN BOOLEAN MODE) AS score FROM Posts WHERE MATCH(post) AGAINST('%s*' IN BOOLEAN MODE)",
mysql_real_escape_string($_GET['searchterm']),
mysql_real_escape_string($_GET['searchterm']));
$results = $db->queryAsArray($sql);
如果您将 %27) SQL INJECTION HERE %2F*
传递到搜索词查询字符串,我会在页面上输出:
您的 SQL 语法有错误; 检查对应的手册 您的 MySQL 服务器版本 在 'BOOLEAN 附近使用正确的语法 MODE)' 在第 1 行
感谢大家在 db 类中发现问题。
So using %27 you can just SQL inject even though data is sanitized with mysql_real_escape_string
%27) SQL INJECTION HERE %2F*
What to do?
Edit with example:
$sql = sprintf("SELECT *, MATCH(post) AGAINST ('%s*' IN BOOLEAN MODE) AS score FROM Posts WHERE MATCH(post) AGAINST('%s*' IN BOOLEAN MODE)",
mysql_real_escape_string($_GET['searchterm']),
mysql_real_escape_string($_GET['searchterm']));
$results = $db->queryAsArray($sql);
If you pass in %27) SQL INJECTION HERE %2F*
to the searchterm querystring, I get outputted on the page:
You have an error in your SQL syntax;
check the manual that corresponds to
your MySQL server version for the
right syntax to use near 'BOOLEAN
MODE)' at line 1
Thanks everyone for finding the problem in the db class..
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从方法名称
queryAsArray
推理,您似乎正在使用 这个DbBase类来自MySQL函数手册页的注释。如果是这样,则query
方法会从转义引号中删除转义字符:那么您的示例有效(我简化了它)就不是奇迹了:
Reasoning from the method name
queryAsArray
, it seems that you’re using this DbBase class from the comments of the MySQL functions manual page. If so, it’s thequery
method that removes the escape character from the escaped quotation marks:Then it’s not a miracle that your example works (I simplified it):
我们手册中提到的注释已被标记为删除。一旦它传播到我们网络中的所有镜像,它将不再出现在官方文档中。
The note mentioned in our manual has been marked for deletion. Once it propagates across all of the mirrors in our network, it will no longer appear attached to the official documentation.
最好根本不要构建这样的语句,而是使用 mysqli 或 PDO 来使用带有参数的查询。这将解决 MySQL 注入的问题,并且有一天(不幸的是,还没有)它也会执行得更好,因为查询是在没有参数的情况下缓存的,这意味着您在缓存中只有一个查询,而不是几十个不同的查询,因为单个输入值一直在变化。其他数据库很早就使用了这一点,但 MySQL 自最新版本以来只是设法不让参数化查询变慢。
%27 实际上会终止字符串,这看起来不太合理。这似乎更像是在字符串中嵌入引号的可能性,但我不确定。
可以肯定的是,我决定牺牲我的服务器来测试它。当我在输入字段和文本区域中输入 %27 并使用 mysql_real_escape_string 转义然后插入数据库时,我没有收到任何错误。文本
%27
刚刚插入。所以完全没问题。It's best to not to build statements like this at all, and instead use queries with parameters using mysqli or PDO. This will deal with the problem of MySQL injection and one day (not yet, unfortunately) it will perform better too, because the queries are cached without parameters, meaning you only got one query in the cache instead of dozens of different queries because of a single input value changing all the time. Other databases make use of this since long, but MySQL just managed not to make parameterized queries slower since the latest version.
It doesn't look plausible that %27 will actually terminate the string. It seems more like a possibility to embed quotes inside a string, but I'm not sure.
To be sure, I decided to sacrificed my server and test this. When I enter %27 in an input field and textarea that are escaped using mysql_real_escape_string and are then inserted in the database, I get no errors. The text
%27
is just inserted. So no problem at all.您错了。这里不可能进行注射。
通过遵循这三个简单的规则,
mysql_set_charset()
正确设置,using mysql_real_escape_string()
您可以确保不可能进行注入
You are wrong. No injection possible here.
By following these three simple rules
mysql_set_charset()
using mysql_real_escape_string()
you can be sure that no injection possible