Skip to content

Commit b3e4021

Browse files
committed
feat(express): support for the body-parser module
1 parent 376e6d1 commit b3e4021

File tree

4 files changed

+54
-65
lines changed

4 files changed

+54
-65
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,18 @@ app.use(protect.express.xss())
3131

3232
Returns an Express middleware, which checks for SQL injections.
3333

34-
* `options.body`: if this options is set, the middleware will check for request bodies - options passed here are passed to the `raw-body` module
34+
* `options.body`: if this options is set (`true`), the middleware will check for request bodies as well
35+
* default: `false`
36+
* prerequisite: you must have the [body-parser](https://github.com/expressjs/body-parser) module used before adding the protect middleware
3537
* `options.loggerFunction`: you can provide a logger function for the middleware to log attacks
38+
* default: `noop`
3639

3740
#### `protect.express.xss([options])`
3841

3942
Returns an Express middleware, which checks for XSS attacks.
4043

41-
* `options.body`: if this options is set, the middleware will check for request bodies - options passed here are passed to the `raw-body` module
44+
* `options.body`: if this options is set (`true`), the middleware will check for request bodies
45+
* default: `false`
46+
* prerequisite: you must have the [body-parser](https://github.com/expressjs/body-parser) module used before adding the protect middleware
4247
* `options.loggerFunction`: you can provide a logger function for the middleware to log attacks
48+
* default: `noop`

lib/express/index.js

Lines changed: 24 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
'use strict'
22

3-
const rawbody = require('raw-body')
43
const rules = require('../rules')
54

5+
function getBodyAsString (body) {
6+
if (typeof body === 'object') {
7+
return JSON.stringify(body)
8+
} else if (Buffer.isBuffer(body)) {
9+
return body.toString('utf-8')
10+
}
11+
12+
return body
13+
}
14+
615
function sqlInjection (options = {}) {
716
const { loggerFunction = noop } = options
817

918
return (request, response, next) => {
10-
request._protect = request._protect || {}
1119
// return 403 if SQL injection found
1220
if (rules.isSqlInjection(request.originalUrl)) {
1321
loggerFunction('sql-injection', {
@@ -17,31 +25,15 @@ function sqlInjection (options = {}) {
1725
}
1826

1927
if (options.body) {
20-
if (request._protect.body) {
21-
if (rules.isXss(request._protect.body)) {
22-
loggerFunction('xss', {
23-
body: request._protect.body
24-
})
25-
return response.sendStatus(403)
26-
}
27-
return next()
28+
const body = getBodyAsString(request.body)
29+
30+
if (rules.isSqlInjection(body)) {
31+
loggerFunction('sql-injection', {
32+
body
33+
})
34+
return response.sendStatus(403)
2835
}
29-
return rawbody(request, Object.assign({}, options.body, {
30-
encoding: 'utf-8'
31-
}))
32-
.then((body) => {
33-
request._protect.body = body
34-
if (rules.isSqlInjection(body)) {
35-
loggerFunction('sql-injection', {
36-
body
37-
})
38-
return response.sendStatus(403)
39-
}
40-
return next()
41-
})
42-
.catch((error) => {
43-
next(error)
44-
})
36+
return next()
4537
}
4638

4739
return next()
@@ -52,7 +44,6 @@ function xss (options = {}) {
5244
const { loggerFunction = noop } = options
5345

5446
return (request, response, next) => {
55-
request._protect = request._protect || {}
5647
// return 403 if XSS found
5748
if (rules.isXss(request.originalUrl)) {
5849
loggerFunction('xss', {
@@ -62,31 +53,13 @@ function xss (options = {}) {
6253
}
6354

6455
if (options.body) {
65-
if (request._protect.body) {
66-
if (rules.isXss(request._protect.body)) {
67-
loggerFunction('xss', {
68-
body: request._protect.body
69-
})
70-
return response.sendStatus(403)
71-
}
72-
return next()
56+
const body = getBodyAsString(request.body)
57+
if (rules.isXss(body)) {
58+
loggerFunction('xss', {
59+
body
60+
})
61+
return response.sendStatus(403)
7362
}
74-
return rawbody(request, Object.assign({}, options.body, {
75-
encoding: 'utf-8'
76-
}))
77-
.then((body) => {
78-
request._protect.body = body
79-
if (rules.isXss(body)) {
80-
loggerFunction('xss', {
81-
body
82-
})
83-
return response.sendStatus(403)
84-
}
85-
return next()
86-
})
87-
.catch((error) => {
88-
next(error)
89-
})
9063
}
9164

9265
return next()

lib/express/index.spec.js

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
const request = require('supertest')
44
const express = require('express')
5+
const bodyParser = require('body-parser')
6+
57
const lib = require('../')
68

79
describe('The express object', () => {
@@ -32,16 +34,22 @@ describe('The express object', () => {
3234

3335
it('can block requests based on the body payload', () => {
3436
const app = express()
37+
app.use(bodyParser.urlencoded({
38+
extended: true
39+
}))
3540
app.use(lib.express.sqlInjection({
36-
body: {}
41+
body: true
3742
}))
3843
app.post('/login', (req, res) => {
3944
res.send('ok')
4045
})
4146

4247
return request(app)
4348
.post('/login')
44-
.field('password', '; OR 1=1')
49+
.type('form')
50+
.send({
51+
password: 'passowrd\' OR 1=1'
52+
})
4553
.expect(403)
4654
})
4755
})
@@ -73,38 +81,42 @@ describe('The express object', () => {
7381

7482
it('can block requests based on the body payload', () => {
7583
const app = express()
84+
app.use(bodyParser.json())
7685
app.use(lib.express.xss({
77-
body: {}
86+
body: true
7887
}))
7988
app.post('/login', (req, res) => {
8089
res.send('ok')
8190
})
8291

8392
return request(app)
8493
.post('/login')
85-
.field('password', '<script>')
94+
.send({
95+
password: '<script>'
96+
})
8697
.expect(403)
8798
})
8899
})
89100

90101
describe('together', () => {
91102
it('works', () => {
92103
const app = express()
104+
app.use(bodyParser.json())
93105
app.use(lib.express.xss({
94-
body: {}
106+
body: true
95107
}))
96108
app.use(lib.express.sqlInjection({
97-
body: {
98-
limit: '1mb'
99-
}
109+
body: true
100110
}))
101111
app.post('/login', (req, res) => {
102112
res.send('ok')
103113
})
104114

105115
return request(app)
106116
.post('/login')
107-
.field('password', '<script>')
117+
.send({
118+
password: '<script>'
119+
})
108120
.expect(403)
109121
})
110122
})

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"author": "",
1616
"license": "MIT",
1717
"devDependencies": {
18+
"body-parser": "1.17.1",
1819
"chai": "3.5.0",
1920
"co-mocha": "1.2.0",
2021
"eslint": "3.19.0",
@@ -29,8 +30,5 @@
2930
"sinon-chai": "2.10.0",
3031
"supertest": "3.0.0",
3132
"traverse": "0.6.6"
32-
},
33-
"dependencies": {
34-
"raw-body": "2.2.0"
3533
}
3634
}

0 commit comments

Comments
 (0)