Mysql SQL中的And或条件,但未正确嵌套它们
我正在尝试SQLi攻击 编译器不顾警告执行以下查询:Mysql SQL中的And或条件,但未正确嵌套它们,mysql,sql,logical-operators,Mysql,Sql,Logical Operators,我正在尝试SQLi攻击 编译器不顾警告执行以下查询: select * from users where username='A' or 'B' and password='C'; 由于查询已执行,因此攻击成功。为什么这个查询有效?它在做什么?我可以假设值“B”在布尔意义上被视为“True”吗?逻辑运算符如何相互作用?数学有没有像博德马斯那样的特殊顺序?请注意,“B”是独立的,不是布尔条件 上述格式的查询在mysql数据库中运行良好,返回与查询相同的结果: select * from user
select * from users where username='A' or 'B' and password='C';
由于查询已执行,因此攻击成功。为什么这个查询有效?它在做什么?我可以假设值“B”在布尔意义上被视为“True”吗?逻辑运算符如何相互作用?数学有没有像博德马斯那样的特殊顺序?请注意,“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)
当您编写这样的查询时,查询分析器将抛出一个语法错误 SQL不允许以“或”分隔的值列表的语法结构,mu必须“ORize”所有条件:
select * from users where (username='A' or user_name='B') and password='C';
此处需要括号,因为AND运算符优先于OR运算符,因此不带括号的查询被视为username='A'或(user_name='B'和password='C')
还有一个建议:不要在数据库中存储密码。数据库不应处理纯文本密码,用户凭据验证应在应用程序级别而不是数据库级别进行管理。存储加密密码散列,从应用程序级别检索它们并在那里进行验证。此外,如果在Web环境中工作,强烈建议在客户端(浏览器)层加密密码或使用SSL。当您编写这样的查询时,查询分析器将抛出语法错误 SQL不允许以“或”分隔的值列表的语法结构,mu必须“ORize”所有条件:
select * from users where (username='A' or user_name='B') and password='C';
此处需要括号,因为AND运算符优先于OR运算符,因此不带括号的查询被视为username='A'或(user_name='B'和password='C')
还有一个建议:不要在数据库中存储密码。数据库不应处理纯文本密码,用户凭据验证应在应用程序级别而不是数据库级别进行管理。存储加密密码散列,从应用程序级别检索它们并在那里进行验证。此外,如果在Web环境中工作,强烈建议在客户端(浏览器)层加密密码或使用SSL。这有一个适当的表,显示T-SQL的操作顺序
假设您修复了查询中的小语法错误,您将返回以下内容:
- 用户名为“B”,密码为“C”
- 用户名为“a”
select * from users where username='A' or username = 'B' and password='C';
这是一个不错的表,显示了T-SQL的操作顺序
假设您修复了查询中的小语法错误,您将返回以下内容:
- 用户名为“B”,密码为“C”
- 用户名为“a”
select * from users where username='A' or username = 'B' and password='C';
如果“B”不是布尔值,则需要指定要与之进行比较的内容,在本例中可能是
username
有点像
select * from users where username='A' or username='B' and password='C'
这将计算username='B'和password='C'
,然后计算或username='A'
你也可以参考这篇文章
您可以找到SQL运算符排序。如果“B”不是布尔值,则需要指定要与之进行比较的对象,在本例中,该对象可能是
用户名
有点像
select * from users where username='A' or username='B' and password='C'
这将计算username='B'和password='C'
,然后计算或username='A'
你也可以参考这篇文章
您可以找到SQL运算符排序。更新 根据您更新的问题和评论,您似乎已经意识到语法中的错误,并且想知道MySQL是如何处理此查询的 看起来MySQL首先将字符串转换为整数值(产生警告) MySQL处理any,因此将'B'转换为整数后,将计算为
TRUE
首先,我认为您的查询在我所知道的任何DBMS中都是无效的。既然你说‘B’不是布尔条件,那么我不得不认为你的意思是:
select * from users where username IN ( 'A', 'B' ) and password='C';
当然,这会使你的问题无效。为了回答您的核心问题,我将您的SQL改为:
select * from users where username='A' or username='B' and password='C';
这将取决于DBMS以及它如何选择解析SQL。一般来说,和
应该优先于或
,但很明显,软件开发人员可以随意实现SQL,因此我相信如果您足够努力的话,您可以找到反例(例如,可能是一个按顺序处理布尔运算符的DBMS)
SQL Server将在或
MySQL还将在或
Sybase将在或
DB2与其他数据库一样,将在或之前处理和
即使是我所知道的最不符合标准的SQL实现之一MS Access也保留了和-before-或的优先级:
更新
根据您更新的问题和评论,您似乎已经意识到语法中的错误,并且想知道MySQL是如何处理此查询的
看起来MySQL首先将字符串转换为整数值(产生警告)
MySQL处理any,因此将'B'转换为整数后,将计算为TRUE
首先,我认为您的查询在我使用的任何DBMS中都是无效的
username='A' or ( username='B' and password='C' )
username='A' or ( username='B' and password='C' )