diff --git a/index.js b/index.js index d66d7e4..7efd5cc 100644 --- a/index.js +++ b/index.js @@ -5,6 +5,7 @@ var crypto = require('crypto') var EventEmitter = require('events').EventEmitter var inherits = require('inherits') +var MAX_METADATA_SIZE = 10000000 // 10MB var BITFIELD_GROW = 1000 var PIECE_LENGTH = 16 * 1024 @@ -28,8 +29,8 @@ module.exports = function (metadata) { this._fetching = false // The largest .torrent file that I know of is ~1-2MB, which is ~100 pieces. - // Therefore, cap the bitfield to 1,000 bits so a malicious peer can't make it grow - // to fill all memory. + // Therefore, cap the bitfield to 10x that (1000 pieces) so a malicious peer can't + // make it grow to fill all memory. this._bitfield = new BitField(0, { grow: BITFIELD_GROW }) if (Buffer.isBuffer(metadata)) { @@ -52,6 +53,10 @@ module.exports = function (metadata) { return this.emit('warning', new Error('Peer does not have metadata')) } + if (handshake.metadata_size > MAX_METADATA_SIZE) { + return this.emit('warning', new Error('Peer gave maliciously large metadata size')) + } + this._metadataSize = handshake.metadata_size this._numPieces = Math.ceil(this._metadataSize / PIECE_LENGTH) this._remainingRejects = this._numPieces * 2