Vulnerability Note
1 Summary
The gateway mode in js-ipfs
provides an autogenerated directory listing for ipfs CID’s that resolve to a folder. This directory listing is generated by ipfs-http-response. The problem is that the dir-view
component in ipfs-http-response
does not encode CID metadata for use in HTML before string-concatenating it into a static HTML dir-viewer page that is later served via the js-ipfs
HTTP gateway.
The severity is rather low, though, due to the nature of this injection one could easily deploy a HTML CID instead to achieve a similar result. However, things might get more interesting if this package is being used in a more privileged context.
2 Details
2.1 Description
The dir-view/index.js component returns a HTML rendered directory listing. Link.name
(any any other untrusted inputs) are not encoded before being inserted in the HTML template. This allows for HTML/Script injection on the dir-view page.
2.2 Proof of Concept
- let’s create a new folder with files containing HTML chars (note that we can directly manipulate ipfs CID links by creating CIDs manually)
⇒ IPFS_PATH=./ipfs3 IPFS_LOGGING=debug node ../../../js/js-ipfs/packages/ipfs/src/cli.js add -r -w "testi"
added QmWsCoFw8wtya9U9QQRfso93puB7HuhPdeQ8smMJudb4ja testi/<hr><hr>oo
added QmVhSdefteV6RbzhEywrPmt1qsa3LdNudgBxANgo4s4PDJ testi/<marquee>yolohi
added QmWR8w4Q7CVJ4zDmYX7zWkcrPdy7GCVv8XYZhoc1PJswhg testi/yay
added QmagxXdk5L29XMc1ZbWaoewQqJLzK9qrUaHLkR5RA3EmJQ testi
added Qmbw1zpg677H9P74vt1vTM1zQtUabvd2Fi6HaKDn6krJtR
-
run ipfs in daemon mode:
⇒ IPFS_PATH=./ipfs3 IPFS_LOGGING=debug node ../../../js/js-ipfs/packages/ipfs/src/cli.js daemon
-
navigate to CID
Qmbw1zpg677H9P74vt1vTM1zQtUabvd2Fi6HaKDn6krJtR
2.3 Proposed Fix
Properly encode link attributes before using them in the context of an HTML webpage. Use a template enginge that automatically encodes inputs for use within HTML.
3 Vendor Response
Vendor response: fixes [email protected] and [email protected].
3.1 Timeline
JUL/28/2021 - shared with security[at]ipfs
SEP/08/2021 - fixed with [email protected] ([email protected])