Skip to content

Commit

Permalink
Merge pull request from GHSA-qh73-qc3p-rjv2
Browse files Browse the repository at this point in the history
  • Loading branch information
mcollina authored Feb 11, 2022
1 parent 25c0bed commit a70dc70
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 4 deletions.
8 changes: 4 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ function attachToBody (options, req, reply, next) {
}, options)

mp.on('field', (key, value) => {
if (key === '__proto__') {
mp.destroy(new Error('__proto__ is not allowed as field name'))
if (key === '__proto__' || key === 'constructor') {
mp.destroy(new Error(`${key} is not allowed as field name`))
return
}
if (body[key] === undefined) {
Expand Down Expand Up @@ -257,8 +257,8 @@ function fastifyMultipart (fastify, options, done) {
log.debug({ field, filename, encoding, mimetype }, 'parsing part')
files++
eos(file, waitForFiles)
if (field === '__proto__') {
file.destroy(new Error('__proto__ is not allowed as field name'))
if (field === '__proto__' || field === 'constructor') {
file.destroy(new Error(`${field} is not allowed as field name`))
return
}
handler(field, file, filename, encoding, mimetype)
Expand Down
46 changes: 46 additions & 0 deletions test/legacy/append-body.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -785,3 +785,49 @@ test('addToBody with __proto__ field', t => {
})
})
})

test('addToBody with constructor field', t => {
t.plan(3)

const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))

const opts = {
addToBody: true,
onFile: (fieldName, stream, filename, encoding, mimetype) => {
t.fail('there are not stream')
}
}
fastify.register(multipart, opts)

fastify.post('/', function (req, reply) {
t.fail('should not be called')
})

fastify.listen(0, function () {
// request
const form = new FormData()
const opts = {
protocol: 'http:',
hostname: 'localhost',
port: fastify.server.address().port,
path: '/',
headers: form.getHeaders(),
method: 'POST'
}

const req = http.request(opts, (res) => {
t.equal(res.statusCode, 500)
res.resume()
res.on('end', () => {
t.pass('res ended successfully')
})
})

form.append('myField', 'hello')
form.append('constructor', 'world')
pump(form, req, function (err) {
t.error(err, 'client pump: no err')
})
})
})
52 changes: 52 additions & 0 deletions test/legacy/multipart.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -478,3 +478,55 @@ test('should not allow __proto__', { skip: process.platform === 'win32' }, funct
})
})
})

test('should not allow constructor', { skip: process.platform === 'win32' }, function (t) {
t.plan(5)

const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))

fastify.register(multipart, { limits: { fields: 1 } })

fastify.post('/', function (req, reply) {
t.ok(req.isMultipart())

const mp = req.multipart(handler, function (err) {
t.equal(err.message, 'constructor is not allowed as field name')
reply.code(500).send()
})

mp.on('field', function (name, value) {
t.fail('should not be called')
})

function handler (field, file, filename, encoding, mimetype) {
t.fail('should not be called')
}
})

fastify.listen(0, function () {
// request
const form = new FormData()
const opts = {
protocol: 'http:',
hostname: 'localhost',
port: fastify.server.address().port,
path: '/',
headers: form.getHeaders(),
method: 'POST'
}

const req = http.request(opts, (res) => {
t.equal(res.statusCode, 500)
res.resume()
res.on('end', () => {
t.pass('res ended successfully')
})
})
const rs = fs.createReadStream(filePath)
form.append('constructor', rs)
pump(form, req, function (err) {
t.error(err, 'client pump: no err')
})
})
})

0 comments on commit a70dc70

Please sign in to comment.