Permalink
Browse files

Feature: IncomingForm.maxFieldSize

The parser is now considered safe. A malicious client can no longer
allocate huge amounts of memory by sending a big field.
  • Loading branch information...
1 parent bf21f0c commit d99eea00521383215d0f07d39c25a30ba9a149b3 @felixge committed Jul 17, 2010
Showing with 30 additions and 1 deletion.
  1. +6 −1 Readme.md
  2. +7 −0 lib/formidable/incoming_form.js
  3. +17 −0 test/simple/test-incoming-form.js
View
@@ -14,7 +14,6 @@ A node.js module for dealing with web forms.
### Todo
-* Limit buffer size for fields
* Implement QuerystringParser the same way as MultipartParser
## Installation
@@ -86,6 +85,12 @@ If you want the files written to `incomingForm.uploadDir` to include the extensi
Either 'multipart' or 'urlencoded' depending on the incoming request.
+#### incomingForm.maxFieldSize = 2 * 1024 * 1024
+
+Limits the amount of memory a field (not file) can allocate in bytes.
+I this value is exceeded, an `'error'` event is emitted. The default
+size is 2MB.
+
#### incomingForm.bytesReceived
The amount of bytes received for this form so far.
@@ -14,6 +14,7 @@ function IncomingForm() {
this.error = null;
this.ended = false;
+ this.maxFieldSize = 2 * 1024 * 1024;
this.keepExtensions = false;
this.uploadDir = '/tmp';
this.encoding = 'utf-8';
@@ -25,6 +26,7 @@ function IncomingForm() {
this._parser = null;
this._flushing = 0;
+ this._fieldsSize = 0;
};
sys.inherits(IncomingForm, EventEmitter);
exports.IncomingForm = IncomingForm;
@@ -146,6 +148,11 @@ IncomingForm.prototype.handlePart = function(part) {
, decoder = new StringDecoder(this.encoding);
part.addListener('data', function(buffer) {
+ self._fieldsSize += buffer.length;
+ if (self._fieldsSize > self.maxFieldSize) {
+ self._error(new Error('maxFieldSize exceeded, received '+self._fieldsSize+' bytes of field data'));
+ return;
+ }
value += decoder.write(buffer);
});
@@ -31,8 +31,10 @@ test(function constructor() {
assert.strictEqual(form.encoding, 'utf-8');
assert.strictEqual(form.bytesReceived, null);
assert.strictEqual(form.bytesExpected, null);
+ assert.strictEqual(form.maxFieldSize, 2 * 1024 * 1024);
assert.strictEqual(form._parser, null);
assert.strictEqual(form._flushing, 0);
+ assert.strictEqual(form._fieldsSize, 0);
assert.ok(form instanceof EventEmitterStub);
assert.equal(form.constructor.name, 'IncomingForm');
});
@@ -550,6 +552,21 @@ test(function handlePart() {
PART.emit('end');
})();
+ (function testFieldSize() {
+ form.maxFieldSize = 8;
+ var PART = new events.EventEmitter();
+ PART.name = 'my_field';
+
+ gently.expect(form, '_error', function(err) {
+ assert.equal(err.message, 'maxFieldSize exceeded, received 9 bytes of field data');
+ });
+
+ form.handlePart(PART);
+ form._fieldsSize = 1;
+ PART.emit('data', new Buffer(7));
+ PART.emit('data', new Buffer(1));
+ })();
+
(function testFilePart() {
var PART = new events.EventEmitter()
, FILE = new events.EventEmitter()

0 comments on commit d99eea0

Please sign in to comment.