ignore peers who report maliciously large metadata

This commit is contained in:
Feross Aboukhadijeh 2014-08-17 03:06:45 -07:00
parent 478cb13670
commit 9c7f5da432
1 changed files with 7 additions and 2 deletions

View File

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