Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vulnerbility report - Established WebSocket session remains open #2

Closed
dz2742-sponsor opened this issue Sep 11, 2023 · 14 comments
Closed

Comments

@dz2742-sponsor
Copy link

Hi,
I came for the bug bounty and I found one, what is the recommended way of communicating the details?
Thank you

@matusfaro
Copy link
Owner

Hi @dz2742,

Honestly I just released this extension yesterday so a zero-day is probably not an issue to discuss publicly. You can post it here.

@dz2742-sponsor
Copy link
Author

dz2742-sponsor commented Sep 11, 2023

Changing proxy settings doesn't disconnect established WebSocket session
PoC:

<!DOCTYPE html>
<html>
<script>
const websocket = new WebSocket("wss://" + location.host + "/ws");
let logs = "";
websocket.addEventListener('message', event => {
  logs = event.data + "\n" + logs;
  document.body.innerText = logs;
});
setInterval(()=>{
  websocket.send(Math.random());
}, 1000);
</script>
<img src="/delay">
</html>

@matusfaro
Copy link
Owner

Nice catch, thank you for your work!

I think that constitutes a full exploit and deserves the entire 100 USD in the pool. Would you like to donate some of that back for future reports? Let me know if so.

Otherwise, do you accept bitcoin/cardano? Post your address here or send me an email at matus at matus io

@dz2742-sponsor
Copy link
Author

My pleasure, also congratulations on trending on HN front page!

I would like to donate to other projects on Github, would you mind making a few one-time sponsorships in my place?

@dz2742-sponsor dz2742-sponsor changed the title Security vulnerbility reporting Vulnerbility report - Established WebSocket session remains open Sep 11, 2023
@matusfaro
Copy link
Owner

Yes of course and thank you!

Do you have specific projects in mind? If not, I will look for some that I've used recently and post back here.

@dz2742-sponsor
Copy link
Author

I would like to donate 20 USD to each of them and the remaining 20 USD is yours, thank you 😃

@matusfaro
Copy link
Owner

matusfaro commented Sep 11, 2023

Sponsorships sent

I'll think of you dz2742 when I buy a beer with that twenty. :)

P.S. Feel free to submit more vulnerabilities, I replenished the pool for another 100 USD.

@matusfaro
Copy link
Owner

As far as my research goes, there doesn't seem to be a way to cut network access for in-progress connections from an Addon.

Suppression for websockets specifically is to simply block all websockets in our container even before network lock is requested.

However I believe the vulnerability still exists for other connections so I am leaving this issue open while I look into it.

Particularly, any request body can be a ReadableStream that I predict will stay open for as long as I keep the stream open. I will do a POC to verify this.

Any suggestions on how to fix this are welcome.

@Alan-Liang
Copy link

Alan-Liang commented Sep 12, 2023

It seems that WebRTC also enables data leaks, which is totally not surprising.

TL; DR: Established WebRTC session remains open.

A simple POC using peerjs:

  1. Open https://lab.olic.link/rtc/attacker.html in a normal browser tab
  2. Open https://lab.olic.link/rtc/victim.html in an isolated tab
  3. Wait for victim.html to finish connection
  4. Verify that the WS connection on victim.html has been closed (the WS is for connection brokering only, it is possible to leak data without a WS connection; it's there just because peerjs use websockets.)
  5. Click "block network"
  6. Verify that message could still be sent from victim.html to attacker.html

@dz2742-sponsor
Copy link
Author

Firefox has an offline mode (Alt key to bring out the menu bar - File - Work Offline) from the good old days, enabling it cuts existing connections including WebSocket. It's browser-wide so other tabs (especially video conference) will be affected.
https://addons.mozilla.org/en-US/firefox/addon/work-offline-page-only/
https://github.com/Emano-Waldeck/work-offline/

@matusfaro
Copy link
Owner

@dz2742

Firefox has an offline mode

Unfortunately, it's not possible to control this through an extension. The homepage of the first extension contains "...except already connected WebSocket connections" and the second link uses chrome.webRequest.onBeforeRequest which only intercepts new requests as well.

However, there are three attack vectors I identified and here are the best solutions I could come up with:

  1. Websockets: Simply block all websockets for the entire duration of the Container even before "block network".
  2. WebRTC: Disable WebRTC globally in Firefox for the duration of our temporary Containers. (Not possible to enable per tab/container)
  3. Long streaming/polling HTTP requests: Add a listener for request open and close and keep a running count of active connections. Wait until all connections are closed before indicating to the user the network is locked.

Interesting note:

  • Browser WebRTC implementations typically use websockets for signalling including your POC. Simply blocking websockets broke WebRTC, but in theory you could do signalling over HTTP long polling as well so it's not a reliable way to block WebRTC.

Other things I considered:

  • Reopen/refresh a tab with network lock, hoping all assets are cached. (Still wouldn't block webrtc, but could it work without active signalling?)
  • Inject scripts into the site to attempt to intercept/close webrtc/websockets/http requests (Too fragile)

@dz2742-sponsor
Copy link
Author

Unfortunately, it's not possible to control this through an extension. The homepage of the first extension contains "...except already connected WebSocket connections" and the second link uses chrome.webRequest.onBeforeRequest which only intercepts new requests as well.

According to my testing the extension does cut out existing WebSocket, the second link is its source code.

@matusfaro
Copy link
Owner

According to my testing the extension does cut out existing WebSocket, the second link is its source code.

Thank you for this insight.

I found that the extension does also inject a content script into the page and calls window.stop() which does indeed kill any existing WebSocket connections. This means I can both prevent new connections as well as stop live connections for WebSockets.

For WebRTC however window.stop() has no effect based on my testing. And even if it did, I have no way of preventing new WebRTC connections to start. So I will still have to disable WebRTC globally for the browser for the entire session of my temporary container.

matusfaro added a commit that referenced this issue Sep 14, 2023
- Blocking WebSockets
- Blocking WebRTC
- Tracking open connections, waits for all to close
- Detailed view of each blocking status
@matusfaro
Copy link
Owner

This is now fixed in released version 0.0.3.

Thanks for all your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants