From b98a98760ccabc21975fe036bd574539909a0274 Mon Sep 17 00:00:00 2001 From: Adrian Serrano Date: Mon, 19 Feb 2018 15:55:59 +0100 Subject: [PATCH] Fix out of bounds access to slice in MongoDB parser (#6256) * Fix out of bounds access to slice in MongoDB parser Ignore MongoDB message and drop the TCP stream if a malformed query / response is received, instead of logging a panic. Closes #5188 * Update CHANGELOG --- CHANGELOG.asciidoc | 1 + packetbeat/protos/mongodb/mongodb_parser.go | 3 +++ packetbeat/protos/mongodb/mongodb_test.go | 26 +++++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 403924b4927..b717f148d6d 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -140,6 +140,7 @@ https://github.com/elastic/beats/compare/v6.0.0-beta2...master[Check the HEAD di - Fix mysql SQL parser to trim `\r` from Windows Server `SELECT\r\n\t1`. {pull}5572[5572] - Fix corruption when parsing repeated headers in an HTTP request or response. {pull}6325[6325] - Fix panic when parsing partial AMQP messages. {pull}6384[6384] +- Fix out of bounds access to slice in MongoDB parser. {pull}6256[6256] *Winlogbeat* diff --git a/packetbeat/protos/mongodb/mongodb_parser.go b/packetbeat/protos/mongodb/mongodb_parser.go index 6567c250ee0..4631d518167 100644 --- a/packetbeat/protos/mongodb/mongodb_parser.go +++ b/packetbeat/protos/mongodb/mongodb_parser.go @@ -341,6 +341,9 @@ func (d *decoder) readDocument() (bson.M, error) { start := d.i documentLength, err := d.readInt32() d.i = start + documentLength + if len(d.in) < d.i { + return nil, errors.New("document out of bounds") + } documentMap := bson.M{} diff --git a/packetbeat/protos/mongodb/mongodb_test.go b/packetbeat/protos/mongodb/mongodb_test.go index dc99504b61d..4cc36fc6463 100644 --- a/packetbeat/protos/mongodb/mongodb_test.go +++ b/packetbeat/protos/mongodb/mongodb_test.go @@ -345,3 +345,29 @@ func TestOpCodeNames(t *testing.T) { assert.Equal(t, testData.expected, opCode(testData.code).String()) } } + +// Test for a (recovered) panic parsing document length in request/response messages +func TestDocumentLengthBoundsChecked(t *testing.T) { + logp.TestingSetup(logp.WithSelectors("mongodb", "mongodbdetailed")) + + _, mongodb := mongodbModForTests() + + // request and response from tests/pcaps/mongo_one_row.pcap + reqData, err := hex.DecodeString( + // Request message with out of bounds document + "320000000a000000ffffffffd4070000" + + "00000000746573742e72667374617572" + + "616e7473000000000001000000" + + // Document length (including itself) + "06000000" + + // Document (1 byte instead of 2) + "00") + assert.Nil(t, err) + + tcptuple := testTCPTuple() + req := protos.Packet{Payload: reqData} + private := protos.ProtocolData(new(mongodbConnectionData)) + + private = mongodb.Parse(&req, tcptuple, 0, private) + assert.NotNil(t, private, "mongodb parser recovered from a panic") +}