ORM 注射测试
概述
对象关系映射 (ORM) 注入 是使用 SQL 注入对 ORM 生成的数据访问对象模型的攻击。从测试人员的角度来看,这种攻击实际上与 SQL 注入攻击相同。但是,ORM 层生成的代码中存在注入漏洞。
使用 ORM 工具的好处包括快速生成对象层以与关系数据库通信,标准化这些对象的代码模板,并且它们通常提供一组安全功能来防止 SQL 注入攻击。ORM 生成的对象可以使用 SQL 或在某些情况下使用 SQL 的变体,对数据库执行 CRUD(创建、读取、更新、删除)操作。但是,如果方法可以接受未经清理的输入参数,则使用 ORM 生成对象的 Web 应用程序可能容易受到 SQL 注入攻击。
如何测试
ORM 层很容易出现漏洞,因为它们扩大了攻击面。您不是直接使用 SQL 查询针对应用程序,而是专注于滥用 ORM 层发送恶意 SQL 查询。
识别 ORM 层
为了有效地测试和了解请求和后端查询之间发生的情况,以及与执行正确测试相关的所有内容一样,必须确定所使用的技术。通过遵循信息收集章节,您应该了解手头应用程序正在使用的技术。检查此列表 将语言映射到它们各自的 ORM。
滥用 ORM 层
在确定了可能正在使用的 ORM 之后,了解其解析器的工作原理并研究滥用它的方法变得至关重要,或者即使应用程序使用的是旧版本,也可以识别与正在使用的库相关的 CVE。有时,ORM 层没有正确实现,因此允许测试人员进行正常的 SQL 注入,而不必担心 ORM 层。
弱 ORM 实现
ORM 层未正确实现的易受攻击场景,取自SANS:
List results = session.createQuery("from Orders as orders where orders.id = " + currentOrder.getId()).list();
List results = session.createSQLQuery("Select * from Books where author = " + book.getAuthor()).list();
上面没有实现位置参数,该参数允许开发人员用一个 ?
替换输入。示例如下:
Query hqlQuery = session.createQuery("from Orders as orders where orders.id = ?");
List results = hqlQuery.setString(0, "123-ADB-567-QTWYTFDL").list(); // 0 is the first position, where it is dynamically replaced by the string set
此实现将验证和清理留给 ORM 层完成,绕过它的唯一方法是识别 ORM 层的问题。
易受攻击的 ORM 层
ORM 层大多数时候是代码、第三方库。它们可能像任何其他代码一样容易受到攻击。一个例子可能是 sequelize ORM npm 库 ,该库在 2019 年被发现易受攻击。在 RIPS Tech进行的另一项研究中,在 Java 使用的休眠 ORM 中发现了旁路。
根据他们的博客文章,可以让测试人员识别问题的备忘单概述如下:
DBMS | SQL 注入 |
---|---|
MySQL | abc\' INTO OUTFILE -- |
PostgreSQL | ` = ′ =' =′=chr(61) |
Oracle | NVL(TO_CHAR(DBMS_XMLGEN.getxml('select 1 where 1337>1')),'1')!='1' |
MS SQL | 1<LEN(%C2%A0(select%C2%A0top%C2%A01%C2%A0name%C2%A0from%C2%A0users) |
另一个示例包括 Laravel Query-Builder,它在 2019 年被发现易受攻击。