【问题标题】:And Or conditions in SQL, but not properly nest themSQL 中的 And Or 条件,但未正确嵌套它们
【发布时间】:2013-10-16 13:57:08
【问题描述】:

我正在尝试 SQLi 攻击。

编译器不顾警告执行以下查询:

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

因为查询执行,所以攻击成功。为什么这个查询有效,它在做什么?我可以假设值“B”在布尔意义上被视为“真”吗?逻辑运算符如何相互配合?数学有没有像 BODMAS 这样的特定顺序?请注意,“B”是独立的,而不是布尔条件。

上述格式的查询在mysql数据库中工作正常,返回与查询相同的结果:

select * from users where username='A';

不返回任何语法错误。

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)

【问题讨论】:

  • 我理解,但正如您可能猜到的那样,我正在尝试 SQLi 攻击,并且由于编译器不顾警告执行此查询,攻击是成功的——我想知道它的原因作品。那么,我可以假设值“B”在布尔意义上被视为“真”吗?
  • 好的......你最初的问题很不清楚。您可能应该提到您的意图,您知道这是不正确的语法,并且您想知道 MySQL 中的查询结果,特别是。请参阅我的更新答案。
  • 我已更新您的问题以包含您评论中的信息。如果我误解了,请编辑。

标签: mysql sql logical-operators


【解决方案1】:

更新

根据您更新的问题和 cmets,您似乎知道语法中的错误,并且想具体了解MySQL如何处理此查询。

看起来 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,所以我相信如果你足够努力的话,你会找到反例(也许是一个处理例如,按顺序排列的布尔运算符)。

SQL Server将在OR之前处理AND

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将在OR之前处理AND

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-before-OR 优先级:

http://office.microsoft.com/en-us/access-help/HV080756432.aspx

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

【讨论】:

    【解决方案2】:

    如果“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

    【讨论】:

      【解决方案3】:

      article 有一个不错的表格,显示了 T-SQL 的操作顺序

      假设您修复了查询中的小语法错误,您将返回以下内容:

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

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

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

      【讨论】:

      • 其实并没有语法错误。上述格式的查询在 mysql 中可以正常工作,并返回相同的结果:select * from users where username='A';
      • @MklRjv - 我不会称 1 warning “很好”。警告可能不会阻止您的查询执行,但它们通常意味着查询没有按照您的意思执行。
      【解决方案4】:

      当您编写这样的查询时,查询分析器会抛出语法错误。

      SQL 不允许用“OR”分隔的值列表的语法构造,mu 必须“ORize”所有条件:

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

      这里需要括号,因为AND运算符优先于OR运算符,所以没有括号的查询解释为username='A' or (user_name='B' and password='C')

      一个额外的建议:不要将密码存储在数据库中。数据库不应处理纯文本密码,用户凭据验证应在应用程序级别而不是数据库级别进行管理。存储加密的密码哈希,从应用程序级别检索它们并在那里验证。 Morover,如果在 Web 环境中工作,强烈建议在客户端(浏览器)层加密密码或使用 SSL。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-16
        • 1970-01-01
        • 2014-09-27
        • 1970-01-01
        相关资源
        最近更新 更多