In graphite-web version between 0.9.5 and 0.9.10, a vulnerability exists as a result of unsafe use of the “pickle” module by the product.
The Common Vulnerabilities and Exposures (CVE) project has assigned the name CVE-2013-5093 to this issue. This is an entry on the CVE list (http://cve.mitre.org), which standardizes names for security problems.
2013-08-06 – Vendor contacted
2013-08-06 – Vendor confirms issue
2013-08-07 – Sent CVE request, CVE-2013-5093 is assigned
2013-08-20 – Graphite 0.9.11 released
2013-08-20 – Advisory released
In graphite-web 0.9.5, a “clustering” feature was introduced to allow for scaling for a graphite setup. This was achieved by passing pickles between servers, and it was introduced in this commit.
The function “renderLocalView”, seen below, takes a request that contains a chart type, and a pickle:
start = time()
reqParams = StringIO(request.raw_post_data)
graphType = reqParams.readline().strip()
optionsPickle = reqParams.read()
graphClass = GraphTypes[graphType]
options = pickle.loads(optionsPickle)
image = doImageRender(graphClass, options)
log.rendering("Delegated rendering request took %.6f seconds" % (time() - start))
log.exception("Exception in web.render.views.rawrender")
However due to no explicit safety measures having been implemented to limit the types of objects that can be unpickled, this creates a condition where arbitrary code can be executed, as has been documented by Nelson Elhage.
Proof of concept
The proof of concept can be found as a part of the Metasploit Framework graphite_pickle_exec module.