V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
whoami9894
V2EX  ›  程序员

SQL 语句 where 子句连等

  •  
  •   whoami9894 · 2018-10-22 12:16:18 +08:00 · 2708 次点击
    这是一个创建于 2260 天前的主题,其中的信息可能已经有所发展或是发生改变。

    昨天测试一个网站登录框 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 条回复    2020-04-28 19:39:00 +08:00
    lichao
        1
    lichao  
       2018-10-22 12:25:18 +08:00
    被 SQL 注入了
    lichao
        2
    lichao  
       2018-10-22 12:26:57 +08:00
    请使用 WHERE user = @user and passwd = @passwd 的参数化查询方式
    jzmws
        3
    jzmws  
       2018-10-22 12:43:06 +08:00 via Android
    防止 sql 注入最基本的防护
    whoami9894
        4
    whoami9894  
    OP
       2018-10-22 12:55:36 +08:00
    @lichao
    @jzmws
    ....我当然知道是注入,我就是做安全的,我是不明白 where 字句连等是怎么查询出数据的
    lichao
        5
    lichao  
       2018-10-22 13:29:00 +08:00
    @whoami9894 做安全的怎么会不知道 -- 后面是注释
    lichao
        6
    lichao  
       2018-10-22 13:31:00 +08:00
    @whoami9894 哦,那明白你意思了
    loading
        7
    loading  
       2018-10-22 13:35:39 +08:00 via Android
    拼接字符串,实际拼进去就知道了。
    lichao
        8
    lichao  
       2018-10-22 13:45:39 +08:00
    select * from users where name = 0; 这个出来的结果也很奇怪,MySQL 好奇怪
    lichao
        9
    lichao  
       2018-10-22 13:48:35 +08:00
    PostgreSQL 这种语句就完全不合法
    zjsxwc
        10
    zjsxwc  
       2018-10-22 13:50:12 +08:00
    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
        11
    lichao  
       2018-10-22 13:53:49 +08:00
    @zjsxwc 这是 feature 还是 bug ?
    jjwjiang
        12
    jjwjiang  
       2018-10-22 13:56:47 +08:00
    跟 JS 语法类似,连等先判断头两个,变成了 true 或者 false
    kev17
        13
    kev17  
       2018-10-22 13:57:46 +08:00   ❤️ 1
    (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
        14
    frazy  
       2018-10-22 14:11:05 +08:00
    楼上正解~
    1 就是 true,其他都是 false
    whoami9894
        15
    whoami9894  
    OP
       2018-10-22 15:30:17 +08:00
    @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
        16
    tsparrot  
       2020-04-25 11:21:41 +08:00
    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
        17
    whoami9894  
    OP
       2020-04-25 12:41:28 +08:00
    @tsparrot
    'guest'='admin'='admin' => ('guest'='admin')='admin'
    'guest'='admin' => 0
    0='admin' => 1
    所以查出所有 username != 'admin'的记录
    tsparrot
        18
    tsparrot  
       2020-04-28 19:39:00 +08:00
    @whoami9894 哦哦明白了,谢谢楼主
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2511 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 05:18 · PVG 13:18 · LAX 21:18 · JFK 00:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.