Parity SOP Bypass
Same-Origin Policy Bypass in Parity's Dapp Browser
Disclaimer
/* This program is free software. It comes without any warranty, to * the extent permitted by applicable law. You can redistribute it * and/or modify it under the terms of the GNU General Public License, * Version 2, as published by the Free Software Foundation. See * github.com/tintinweb/pub/tree/master/pocs/cve-2017-18016/ * for more details. */
Issue #1
Same-Origin Policy (SOP) bypass vulnerability due to parity proxying websites
Every webpage you browse to with parity's built-in browser (http://127.0.0.1:8180/#/web) is proxied via http://127.0.0.1:8080.
For example, when you browse to
- http://google.com's the websites origin changes to 127.0.0.1:8080.
- Navigating to http://oststrom.com changes the origin to 127.0.0.1:8080 as it is proxied via parity.
Warning This means, as there's only one origin for all websites, non domain restricted cookies are effectively shared with all websites.
DEMO #1 Cookies shared with other websites
- 1) using parity's built-in browser, navigate to any website to set a cookie (e.g. http://google.com)
- 2) reload this this PoC (https://tintinweb.github.io/pub/pocs/cve-2017-18016/)
- 3) hit the Display Cookies button
Issue #2
Parity WebProxy Token Reuse vulnerability
When navigating to a website with the built-in parity webbrowser a webproxy request token is requested and sent along an encoded request for an url. For example, navigating parity to http://oststrom.com the url gets turned into a proxy url like http://127.0.0.1:8080/web/8X4Q4EBJ71SM2CK6E5AQ6YBNB4NPGX3ME0X2YBVFEDT76X3JDXPJWRVFDM of the form http://127.0.0.1:8080/web/[base32_encode(token+url)].
Warning When navigating to http://oststrom.com the website can detect that it has been proxied by checking the location.href.
It can further base32 decode and extract the web-proxy token and simply reuse it as the token is not bound to any specifiy request url or hostname allowing any website to create proxy urls and navigate to any other website.
Info The parity webbrowser does not allow a proxied website to change the top frames location or open new windows (iframe sandbox).
Warning However, it allows to perform XHR or embed iframes with script access to proxied locations of arbitrary websites. This allows one website to control any other website since they're both same origin (Issue 1).
Info The controlling website has full scripting access to sub-iframes potentially allowing for service enumeration attacks or simulate user interaction.
DEMO #2 Full control of arbitrary websites via token reuse and SOP bypass
- 1) enter url into the textbox
- 2) hit Spawn SOP Iframe
- Note the current page can modify/inject arbitrary DOM/scripting into the iframe, access cookies (only the ones stored for 127.0.0.1, potentially from prevs sessions with parity), manipulate change and reload the websites content (e.g. removing parity's inject.js), get the source via XHR
- Note some websites may not load due to js errors. However, since the website has full control it is likely the calling website can fix any js errors occuring in the subframe.
- Note Untested but likely possible: Prepare a transaction to send off ether via parity/web3 api or xhr, open an iframe or perform requests to directly authorize (may require unlock secret) or redress the UI to clickjack the authorization or perform other actions messing with the users account
DEMO #3 (Chrome) get local lan ip and service scan for web-enabled devices on the LAN to mess with them
e.g. search for local router interfaces with default passwords and reconfigure it to perform DNS based redirection attacks (mitm) or similar
- 1) click 'Find LAN-Local WebInterfaces' to scan for devices listening on http port 80 within your LAN (IP .1 to .254)
- 2) an iframe with full control will be created for each device found on the lan
- Note: might require some fixups for the iframe conted to be loaded completely due to parity webproxy messing with header scripts or websites unable to be loaded via iframes. XHR should work though and CSRF tokens can be read from XHR requests or iframe dom (if dom based). See javascript console for debug.