Check object message payload length

See also: Bitmessage/PyBitmessage#767
This commit is contained in:
Kagami Hiiragi 2015-01-30 17:19:38 +03:00
parent 4ef94e91f7
commit e38c14239e
3 changed files with 61 additions and 7 deletions

View File

@ -388,12 +388,14 @@ var pubkey = exports.pubkey = {
// POW calculation here. // POW calculation here.
var nonce = new Buffer(8); var nonce = new Buffer(8);
// Append signature to the encoded object and we are done. // Append signature to the encoded object and we are done.
return Buffer.concat([ obj = Buffer.concat([
nonce, nonce,
obj, obj,
var_int.encode(sig.length), var_int.encode(sig.length),
sig, sig,
]); ]);
assert(obj.length <= 262144, "object message payload is too big");
return obj;
}); });
return resolve(pubkeyp); return resolve(pubkeyp);
} }
@ -412,7 +414,9 @@ var pubkey = exports.pubkey = {
// POW calculation here. // POW calculation here.
var nonce = new Buffer(8); var nonce = new Buffer(8);
// Concat object header with ecnrypted data and we are done. // Concat object header with ecnrypted data and we are done.
return Buffer.concat([nonce, obj, enc]); obj = Buffer.concat([nonce, obj, enc]);
assert(obj.length <= 262144, "object message payload is too big");
return obj;
}); });
resolve(pubkeyp); resolve(pubkeyp);
}); });
@ -719,7 +723,9 @@ var msg = exports.msg = {
// POW calculation here. // POW calculation here.
var nonce = new Buffer(8); var nonce = new Buffer(8);
// Concat object header with ecnrypted data and we are done. // Concat object header with ecnrypted data and we are done.
return Buffer.concat([nonce, obj, enc]); obj = Buffer.concat([nonce, obj, enc]);
assert(obj.length <= 262144, "object message payload is too big");
return obj;
}); });
resolve(msgp); resolve(msgp);
}); });
@ -981,7 +987,9 @@ var broadcast = exports.broadcast = {
// POW calculation here. // POW calculation here.
var nonce = new Buffer(8); var nonce = new Buffer(8);
// Concat object header with ecnrypted data and we are done. // Concat object header with ecnrypted data and we are done.
return Buffer.concat([nonce, obj, enc]); obj = Buffer.concat([nonce, obj, enc]);
assert(obj.length <= 262144, "object message payload is too big");
return obj;
}); });
resolve(broadp); resolve(broadp);
}); });

View File

@ -61,7 +61,6 @@ var message = exports.message = {
// than default "utf-8" encoding. // than default "utf-8" encoding.
command = command.slice(0, firstNonNull).toString("ascii"); command = command.slice(0, firstNonNull).toString("ascii");
var payloadLength = buf.readUInt32BE(16, true); var payloadLength = buf.readUInt32BE(16, true);
assert(payloadLength <= 262144, "Payload is too big");
var length = 24 + payloadLength; var length = 24 + payloadLength;
assert(buf.length >= length, "Truncated payload"); assert(buf.length >= length, "Truncated payload");
var checksum = buf.slice(20, 24); var checksum = buf.slice(20, 24);
@ -83,7 +82,6 @@ var message = exports.message = {
encode: function(command, payload) { encode: function(command, payload) {
assert(command.length <= 12, "Command is too long"); assert(command.length <= 12, "Command is too long");
assert(isAscii(command), "Non-ASCII characters in command"); assert(isAscii(command), "Non-ASCII characters in command");
assert(payload.length <= 262144, "Payload is too big");
var buf = new Buffer(24 + payload.length); var buf = new Buffer(24 + payload.length);
buf.fill(0); buf.fill(0);
buf.writeUInt32BE(message.MAGIC, 0, true); buf.writeUInt32BE(message.MAGIC, 0, true);
@ -137,6 +135,7 @@ var object = exports.object = {
decodePayload: function(buf) { decodePayload: function(buf) {
// 8 + 8 + 4 + (1+) + (1+) // 8 + 8 + 4 + (1+) + (1+)
assert(buf.length >= 22, "object message payload is too small"); assert(buf.length >= 22, "object message payload is too small");
assert(buf.length <= 262144, "object message payload is too big");
var nonce = new Buffer(8); var nonce = new Buffer(8);
buf.copy(nonce, 0, 0, 8); buf.copy(nonce, 0, 0, 8);
var expiresTime = util.readTimestamp64BE(buf.slice(8, 16)); var expiresTime = util.readTimestamp64BE(buf.slice(8, 16));
@ -198,13 +197,15 @@ var object = exports.object = {
var type = new Buffer(4); var type = new Buffer(4);
type.writeUInt32BE(opts.type, 0); type.writeUInt32BE(opts.type, 0);
var stream = opts.stream || 1; var stream = opts.stream || 1;
return Buffer.concat([ var obj = Buffer.concat([
util.writeUInt64BE(null, expiresTime), util.writeUInt64BE(null, expiresTime),
type, type,
var_int.encode(opts.version), var_int.encode(opts.version),
var_int.encode(stream), var_int.encode(stream),
opts.objectPayload, opts.objectPayload,
]); ]);
assert(obj.length <= 262136, "object message payload is too big");
return obj;
}, },
}; };

45
test.js
View File

@ -167,6 +167,28 @@ describe("Common structures", function() {
objectPayload: Buffer("test"), objectPayload: Buffer("test"),
})).to.throw(Error); })).to.throw(Error);
}); });
it("shouldn't encode message payload bigger than 2^18 bytes", function() {
expect(object.encodePayload.bind(null, {
nonce: Buffer(8),
ttl: 100,
type: object.MSG,
version: 1,
objectPayload: Buffer(300000),
})).to.throw(/too big/i);
});
it("shouldn't decode message payload bigger than 2^18 bytes", function() {
var encoded = object.encodePayload({
nonce: Buffer(8),
ttl: 100,
type: object.MSG,
version: 1,
objectPayload: Buffer("test"),
});
encoded = Buffer.concat([encoded, Buffer(300000)]);
expect(object.decodePayload.bind(null, encoded)).to.throw(/too big/i);
});
}); });
describe("var_int", function() { describe("var_int", function() {
@ -729,6 +751,18 @@ describe("Object types", function() {
expect(res.message).to.equal("Сообщение"); expect(res.message).to.equal("Сообщение");
}); });
}); });
it("shouldn't encode too big msg", function(done) {
return msg.encodeAsync({
ttl: 111,
from: from,
to: from,
message: Buffer(300000),
}).catch(function(err) {
expect(err.message).to.match(/too big/i);
done();
});
});
}); });
describe("broadcast", function() { describe("broadcast", function() {
@ -824,6 +858,17 @@ describe("Object types", function() {
done(); done();
}); });
}); });
it("shouldn't encode too big broadcast", function(done) {
return broadcast.encodeAsync({
ttl: 101,
from: from,
message: Buffer(300000),
}).catch(function(err) {
expect(err.message).to.match(/too big/i);
done();
});
});
}); });
}); });