Skip to content

Commit b88316c

Browse files
benweissmannljharb
authored andcommitted
[Fix] Switch to using crypto random for boundary values
1 parent b70869d commit b88316c

File tree

3 files changed

+59
-9
lines changed

3 files changed

+59
-9
lines changed

lib/form_data.js

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ var http = require('http');
77
var https = require('https');
88
var parseUrl = require('url').parse;
99
var fs = require('fs');
10+
var crypto = require('crypto');
1011
var mime = require('mime-types');
1112
var asynckit = require('asynckit');
1213
var hasOwn = require('hasown');
@@ -357,16 +358,10 @@ FormData.prototype.getBuffer = function () {
357358
};
358359

359360
FormData.prototype._generateBoundary = function () {
360-
/*
361-
* This generates a 50 character boundary similar to those used by Firefox.
362-
* They are optimized for boyer-moore parsing.
363-
*/
364-
var boundary = '--------------------------';
365-
for (var i = 0; i < 24; i++) {
366-
boundary += Math.floor(Math.random() * 10).toString(16);
367-
}
361+
// This generates a 50 character boundary similar to those used by Firefox.
368362

369-
this._boundary = boundary;
363+
// They are optimized for boyer-moore parsing.
364+
this._boundary = '--------------------------' + crypto.randomBytes(12).toString('hex');
370365
};
371366

372367
/*

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@
6262
"obake": "^0.1.2",
6363
"phantomjs-prebuilt": "^2.1.16",
6464
"pkgfiles": "^2.3.2",
65+
"pre-commit": "^1.2.2",
66+
"predict-v8-randomness": "^1.0.35",
67+
"puppeteer": "^1.20.0",
6568
"request": "~2.87.0",
6669
"rimraf": "^2.7.1",
6770
"tape": "^5.9.0"
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use strict';
2+
3+
var common = require('../common');
4+
var assert = common.assert;
5+
var FormData = require(common.dir.lib + '/form_data');
6+
var predictV8Randomness = require('predict-v8-randomness');
7+
8+
var initialSequence = [
9+
Math.random(),
10+
Math.random(),
11+
Math.random(),
12+
Math.random(),
13+
];
14+
var predictor = new predictV8Randomness.Predictor(initialSequence);
15+
16+
predictor.predictNext(24).then(function (next24RandomOutputs) {
17+
var predictedBoundary = next24RandomOutputs
18+
.map(function (v) {
19+
return Math.floor(v * 10).toString(16);
20+
})
21+
.join('');
22+
23+
var boundaryIntro = '----------------------------';
24+
25+
var payload = 'zzz\r\n' + boundaryIntro + predictedBoundary + '\r\nContent-Disposition: form-data; name="is_admin"\r\n\r\ntrue\r\n' + boundaryIntro + predictedBoundary + '--\r\n';
26+
27+
var FIELDS = {
28+
my_field: {
29+
value: payload,
30+
},
31+
};
32+
33+
// count total
34+
var fieldsPassed = Object.keys(FIELDS).length;
35+
36+
// prepare form-receiving http server
37+
var server = common.testFields(FIELDS, function (fields) {
38+
fieldsPassed = fields;
39+
});
40+
41+
server.listen(common.port, function () {
42+
var form = new FormData();
43+
44+
common.actions.populateFields(form, FIELDS);
45+
46+
common.actions.submit(form, server);
47+
});
48+
49+
process.on('exit', function () {
50+
assert.strictEqual(fieldsPassed, 0);
51+
});
52+
});

0 commit comments

Comments
 (0)