• 请不要在回答技术问题时复制粘贴 AI 生成的内容
whoami9894
V2EX  ›  程序员

SQL 语句 where 子句连等

  •  
  •   whoami9894 · Oct 22, 2018 · 3889 views
    This topic created in 2936 days ago, the information mentioned may be changed or developed.

    昨天测试一个网站登录框 user=admin'='admin'-- &passwd=admin 绕过验证了。本地尝试时对连等的行为有点不理解

    mysql> select * from users;
    +----+-----------+----------+
    | id | username  | password |
    +----+-----------+----------+
    |  1 | admin     | admin    |
    |  3 | guest     | abcdefg  |
    |  2 | anonymous | 123456   |
    +----+-----------+----------+
    3 rows in set (0.00 sec)
    
    mysql> select * from users where username='admin'='admin';
    +----+-----------+----------+
    | id | username  | password |
    +----+-----------+----------+
    |  3 | guest     | abcdefg  |
    |  2 | anonymous | 123456   |
    +----+-----------+----------+
    2 rows in set, 1 warning (0.00 sec)
    
    mysql> select * from users where username='admin'='guest';
    +----+-----------+----------+
    | id | username  | password |
    +----+-----------+----------+
    |  3 | guest     | abcdefg  |
    |  2 | anonymous | 123456   |
    +----+-----------+----------+
    2 rows in set, 1 warning (0.00 sec)
    
    mysql> select * from users where username='admin'='a';
    +----+-----------+----------+
    | id | username  | password |
    +----+-----------+----------+
    |  3 | guest     | abcdefg  |
    |  2 | anonymous | 123456   |
    +----+-----------+----------+
    2 rows in set, 1 warning (0.00 sec)
    
    mysql> select * from users where username='admin'='1';
    +----+----------+----------+
    | id | username | password |
    +----+----------+----------+
    |  1 | admin    | admin    |
    +----+----------+----------+
    1 row in set (0.00 sec)
    
    mysql> select * from users where username='admin'='2';
    Empty set (0.00 sec)
    
    

    这里的解析逻辑是怎样的?

    18 replies  •  2020-04-28 19:39:00 +08:00
    lichao
    lichao
    Oct 22, 2018
    1
    被 SQL 注入了
    lichao
    lichao
    Oct 22, 2018
    2
    请使用 WHERE user = @user and passwd = @passwd 的参数化查询方式
    jzmws
    jzmws
    Oct 22, 2018 via Android
    3
    防止 sql 注入最基本的防护
    whoami9894
    whoami9894
    OP
    Oct 22, 2018
    4
    @lichao
    @jzmws
    ....我当然知道是注入,我就是做安全的,我是不明白 where 字句连等是怎么查询出数据的
    lichao
    lichao
    Oct 22, 2018
    5
    @whoami9894 做安全的怎么会不知道 -- 后面是注释
    lichao
    lichao
    Oct 22, 2018
    6
    @whoami9894 哦,那明白你意思了
    loading
    loading
    Oct 22, 2018 via Android
    7
    拼接字符串,实际拼进去就知道了。
    lichao
    lichao
    Oct 22, 2018
    8
    select * from users where name = 0; 这个出来的结果也很奇怪,MySQL 好奇怪
    lichao
    lichao
    Oct 22, 2018
    9
    PostgreSQL 这种语句就完全不合法
    zjsxwc
    zjsxwc
    Oct 22, 2018
    10
    mysql 本来就能连等:



    mysql> select (2=2=2);
    +---------+
    | (2=2=2) |
    +---------+
    | 0 |
    +---------+
    1 row in set (0.00 sec)

    mysql> select (2=2=true);
    +------------+
    | (2=2=true) |
    +------------+
    | 1 |
    +------------+
    1 row in set (0.00 sec)

    mysql> select (2=2=1);
    +---------+
    | (2=2=1) |
    +---------+
    | 1 |
    +---------+
    1 row in set (0.00 sec)
    lichao
    lichao
    Oct 22, 2018
    11
    @zjsxwc 这是 feature 还是 bug ?
    jjwjiang
    jjwjiang
    Oct 22, 2018
    12
    跟 JS 语法类似,连等先判断头两个,变成了 true 或者 false
    kev17
    kev17
    Oct 22, 2018❤️1
    13
    (user= "a" ) = "b"
    会选出最终结果为 true 的行
    例如
    ```

    mysql> select * from users where username='admin'='admin';
    +----+-----------+----------+
    | id | username | password |
    +----+-----------+----------+
    | 3 | guest | abcdefg |
    | 2 | anonymous | 123456 |
    +----+-----------+----------+
    2 rows in set, 1 warning (0.00 sec)
    ```
    结果
    ( 1 ) 第一步 username='admin'的记录返回 1,第二步 true = 'admin' 返回 0,这种记录不会被选择出来

    ( 2 ) 第一步 username <> 'admin'的记录返回 0,第二步 false = 'admin' 返回 1,这种记录会被选择出来
    frazy
    frazy
    Oct 22, 2018
    14
    楼上正解~
    1 就是 true,其他都是 false
    whoami9894
    whoami9894
    OP
    Oct 22, 2018
    15
    @kev17
    ```sql
    mysql> select * from users where false='admin';
    +----+-----------+----------+
    | id | username | password |
    +----+-----------+----------+
    | 1 | admin | admin |
    | 3 | guest | abcdefg |
    | 2 | anonymous | 123456 |
    +----+-----------+----------+
    3 rows in set, 1 warning (0.05 sec)

    mysql> select * from users where true='admin';
    Empty set, 1 warning (0.00 sec)
    ```

    SQL 在 bool 和 str 之间比较的行为好奇怪,0='admin'返回 true

    这样的话就解释通了
    tsparrot
    tsparrot
    Apr 25, 2020
    16
    mysql> select * from users;
    +----+-----------+----------+
    | id | username | password |
    +----+-----------+----------+
    | 1 | admin | admin |
    | 3 | guest | abcdefg |
    | 2 | anonymous | 123456 |
    +----+-----------+----------+
    3 rows in set (0.00 sec)

    mysql> select * from users where username='admin'='admin';
    +----+-----------+----------+
    | id | username | password |
    +----+-----------+----------+
    | 3 | guest | abcdefg |
    | 2 | anonymous | 123456 |
    +----+-----------+----------+
    2 rows in set, 1 warning (0.00 sec)
    楼主你好,请问你帖子里的这个查询返回的结果里为什么会有数据呢( username='admin'返回 1,而 where 1 = ‘str’不是相当于 where 0 吗 为什么会返回数据呢
    whoami9894
    whoami9894
    OP
    Apr 25, 2020
    17
    @tsparrot
    'guest'='admin'='admin' => ('guest'='admin')='admin'
    'guest'='admin' => 0
    0='admin' => 1
    所以查出所有 username != 'admin'的记录
    tsparrot
    tsparrot
    Apr 28, 2020
    18
    @whoami9894 哦哦明白了,谢谢楼主
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2701 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 13:18 · PVG 21:18 · LAX 05:18 · JFK 08:18
    ♥ Do have faith in what you're doing.