作为计算机安全入门课程的一部分,我们有一个关于 SQL 注入的简短单元。其中一项作业是一个基本的未经清理的登录页面。预期的解决方案是沿着经典路线的' or 1=1; --
,但我们始终欢迎学生找到非传统的解决方案。
最近向我提出了这样的解决方案:输入'--'
密码似乎执行了成功的 SQL 注入。这将导致查询被评估为如下所示:
SELECT * FROM users WHERE name='admin' AND password=''--'';
这里,--'';
不被解析为注释,因为 MariaDB 要求注释后面跟空格。事实上,如果双破折号被解析为注释,则该查询根本不会返回任何内容;password=''
同样地,假设密码非空,我们将得到,其计算结果为 false。
末尾的额外一对引号似乎是必要的:将其保留为password=''--;
或在其后面插入其他数据 ( password=''--1;
) 会导致条件被评估为 false,如预期的那样。
一些快速测试无法在其他数据库中重现这种行为——据我所知,这是 MariaDB 特有的行为。该文档确认两个不带空格的破折号不会被解析为注释,但没有详细说明它们被解析为什么。编辑:不知何故,我设法忽略了 MySQL 中也发生这种情况的事实。事实上,这种行为发生在任何 MySQL 分支(不仅仅是 MariaDB)中。
--
当它后面没有空格时会发生什么?为什么它会导致比较结果为 true?
一个玩具示例:
CREATE TABLE users (
userid INTEGER PRIMARY KEY,
username TEXT NOT NULL,
password TEXT NOT NULL
);
INSERT INTO users VALUES (0001, 'admin', 'S3cur3P4ssw0rd!');
INSERT INTO users VALUES (0002, 'generic_user', 'Password');
SELECT * FROM users WHERE username='admin' AND password=''; -- empty password, query returns no users
SELECT * FROM users WHERE username='admin' AND password=''-- ''; -- parsed as comment, equivalent to above query, returns no users
SELECT * FROM users WHERE username='admin' AND password=''--''; -- query returns admin user
SELECT * FROM users WHERE username='admin' AND password=''--; -- query returns zero users
SELECT * FROM users WHERE username='admin' AND password=''--1; -- query returns zero users