关于nodejs mysql module导致的登陆漏洞


在复现第八届封神台CTF时碰到了一个这样的漏洞

这一题的描述如下

我可以很嚣张的告诉你:用户名是admin,后端用的是nodejs,我还用上了数据库,flag就放在后台 不需要任何扫描或爆破,请不要扫描和爆破,这没有意义

部分代码:

var mysql = require("mysql");
if (username && password) {
pool.query(
"SELECT * FROM accounts WHERE username = ? AND password = ?",

这里使用了参数化查询(?作为占位符),这是防止SQL注入的好做法

但是

我们现在将改变password参数到password[password]使参数为Object而不是String.

我们就可以访问管理员帐户

或者也可以将数据作为 JSON 传递并绕过身份验证

![](关于nodejs mysql module导致的登陆漏洞/1745563696799-2cdd5331-7ced-4369-8a76-83318b1849ff.png)

这是由于某些类型(特别是对象类型)quoted identifiers在被转义函数转义时包含引用的标识符。引用的标识符用于指示数据库、表格、列或此类。有了这个,我们可以引用查询中的其他表或列。

password = obj_key_1 更改为password = password``

自引用的标识符password被视为一列,它最终会成为password = password

现在,如果我们改变obj_val_1为1,它最终将成为(1=1)=1最终返回1。

因此,当密码参数传递为{'password': 1}它最终会转化为``password=1最后绕过了身份验证逻辑。

所以在面对nodejs和mysql的登陆时我们可以
username[username]=1&password[password]=1

来登录

![](关于nodejs mysql module导致的登陆漏洞/1745564157565-c3c4074a-59f0-4837-ae77-33949227a7ab.png)

或者
username=admin&password[password]=1

登录特定用户如admin

![](关于nodejs mysql module导致的登陆漏洞/1745564201946-966e24f7-d3c3-407c-899e-67cade203047.png)

防御方法

解决方法 1:在创建连接时添加 stringifyObjects 选项

添加"stringifyObjects":true调用时的选项mysql.createConnection最终会阻止所有意想不到的行为,当Object在参数中传递。

但是,这可能会影响项目中所有现有的查询,并且当某些查询实际通过时可能会引入另一个问题。Object参数。您可能还想查看变通方法2作为替代方案。

解决方法 2:添加类型检查

解决方法1可能是解决这个问题的最有效和最有效的方法。

然而,前一种解决方法只会阻止任何意想不到的行为。Object独家。其他类型如Array, 数组 ofArray,Boolean仍然可能导致意想不到的问题,因为它仍然根据值类型以不同的方式逃逸。前一种解决方法在许多罕见情况下仍然会引入其他意想不到的行为。

因此,最好添加类型检查代码,使您的代码更加严格。这种解决方法的缺点是,添加类型检查代码并对项目进行维护可能需要花费大量时间和成本。此外,在编写代码时,您可能会错过类型检查。


文章作者: YUNiversity
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 YUNiversity !
评论
  目录