和SQL中的条件,但没有正确嵌套它们

时间:2013-10-16 13:57:08

标签: mysql sql logical-operators

我正在尝试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)

4 个答案:

答案 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

http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.ase_15.0.sqlug/html/sqlug/sqlug102.htm

username='A' or ( username='B' and password='C' )

DB2 与其他人一样,将在AND之前处理OR

http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=%2Fcom.ibm.db2z9.doc.sqlref%2Fsrc%2Ftpc%2Fdb2z_precedenceofoperations.htm

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的操作顺序

假设您在查询中修复了次要语法错误,您将返回以下任何内容:

  • 用户名为“B”,密码为“C”
  • 的用户名为“A”

我相信你的语法应该是这样的

 select * from users where username='A' or username = 'B' and password='C';