我正在尝试SQLi攻击。
尽管有警告,编译器仍会执行以下查询:
select * from users where username='A' or 'B' and password='C';
因为查询执行,攻击成功。为什么这个查询有效,它在做什么?我可以假设在布尔意义上将值'B'视为'True'吗?逻辑运算符如何相互协作?是否有像BODMAS这样的特定订单用于数学?请注意,'B'是独立的,而不是布尔条件。
上述格式的查询在mysql数据库中运行正常,并返回与查询相同的结果:
select * from users where username='A';
不会返回任何syantax错误。
mysql> select * from authentication where user='A' or 'B' and password='C';
+------+----------+
| user | password |
+------+----------+
| A | B |
+------+----------+
1 row in set, 1 warning (0.00 sec)
警告如下:
mysql> show warnings;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1292 | Truncated incorrect INTEGER value: 'B' |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)
答案 0 :(得分:3)
如果'B'不是布尔值,那么您需要指定要比较的内容,在这种情况下可能是username
。
喜欢的东西;
select * from users where username='A' or username='B' and password='C'
这将评估username='B' AND password='C'
,然后评估OR username='A'
您也可以参考此StackOverflow帖子。
您可以找到SQL运算符排序here。
答案 1 :(得分:3)
<强>更新强>
根据您更新的问题和评论,您似乎意识到语法中的错误,并希望了解具体 MySQL 如何处理此查询。< / p>
看起来MySQL首先将字符串转换为整数值(产生警告)。
MySQL处理任何non-zero number as TRUE
,因此'B'在转换为整数后会评估为TRUE
。
首先,我不认为您的查询在我所知道的任何DBMS中都有效。既然你说“B”不是布尔条件,那么我必须认为你的意思是:
select * from users where username IN ( 'A', 'B' ) and password='C';
当然会使您对BODMAS的问题无效。所以,为了回答看似你的核心问题,我将把你的SQL改为:
select * from users where username='A' or username='B' and password='C';
它将取决于DBMS以及它如何选择解析SQL。通常AND
应该优先于OR
,但显然软件开发人员可以自由地实现SQL,所以我相信如果你看起来足够努力,你可以找到反例(或许例如,按顺序处理布尔运算符的DBMS。
SQL Server 将在AND
之前处理OR
http://technet.microsoft.com/en-us/library/ms190276.aspx
username='A' or ( username='B' and password='C' )
MySQL 还会在AND
之前处理OR
http://dev.mysql.com/doc/refman/5.0/en/operator-precedence.html
username='A' or ( username='B' and password='C' )
Sybase 将在AND
OR
username='A' or ( username='B' and password='C' )
DB2 与其他人一样,将在AND
之前处理OR
username='A' or ( username='B' and password='C' )
即使 MS Access ,我所知道的最不符合标准的SQL实施之一,也会保留AND
- 之前 - OR
优先级:
http://office.microsoft.com/en-us/access-help/HV080756432.aspx
username='A' or ( username='B' and password='C' )
答案 2 :(得分:2)
当您编写类似查询时,查询分析器会向您抛出语法错误。
SQL不允许语法构造由“OR”分隔的值列表,mu必须“ORize”所有条件:
select * from users where (username='A' or user_name='B') and password='C';
这里的parenthesys是必需的,因为AND运算符优先于OR运算符,因此没有parenthesys的查询被username='A' or (user_name='B' and password='C')
一个额外的建议:不要将密码存储在数据库中。数据库不应处理纯文本密码,用户凭证验证应在应用程序级别进行管理,而不是在数据库级别进行管理。存储加密的密码哈希值,从应用程序级别检索它们并在那里进行验证。 Morover,如果在Web环境中工作,强烈建议在客户端(浏览器)层加密密码或使用SSL。
答案 3 :(得分:2)
这个article有一个很好的表格,显示了T-SQL的操作顺序
假设您在查询中修复了次要语法错误,您将返回以下任何内容:
我相信你的语法应该是这样的
select * from users where username='A' or username = 'B' and password='C';