scratchfoundation / scratch-link

Device interoperability layer for Windows and MacOS
BSD 3-Clause "New" or "Revised" License
102 stars 83 forks source link

TLS private key distributed in Scratch Link #200

Closed calerga closed 2 years ago

calerga commented 2 years ago

Expected Behavior

The TLS private key for device-manager.scratch.mit.edu, which resolves to 127.0.0.1, shouldn't be distributed. See Sectigo's Certificate Policies section 4.9.1 (Sectigo is the certificate authority; this very link is in the certificate). The TLS private key enables mitm attacks between Scratch and Scratch Link.

Actual Behavior

The TLS private key can be found in the macOS and Windows applications. While the key is encrypted, the symmetric encryption key is stored in the application and can be found in scratch-link/Certificates/convert-certificates.sh. Extracting the encrypted certificate private key from the Scratch Link distribution and decrypting it are trivial. The SHA-256 of scratch-device-manager.pem is 2f5ab4f11432c1049dfa7ff867412b2f8df42b6966194d0afdf59cdf534cdbfe.

Steps to Reproduce

Read:

Operating System and Browser

macOS and Windows.

apple502j commented 2 years ago

Note that this has been a common knowledge since at least 2021. See #191 This could also compromise the scratch.mit.edu domain cookies. (Demonstrated by @easrng in a now-deleted? issue)

apple502j commented 2 years ago

@calerga Could you revoke the cert? At least one of them is from Let's Encrypt, so https://letsencrypt.org/docs/revoking/ could be used. I'm stuck at "SubjectPublicKeyInfo" part though.

calerga commented 2 years ago

@apple502j Yes. Lost private keys (what's bracketed by BEGIN PRIVATE KEY/END PRIVATE KEY in the decrypted scratch-device-manager.pem.enc) can be uploaded to Sectigo's revocation portal.

apple502j commented 2 years ago

Seems like it's already revoked.

easrng commented 2 years ago

The aformentioned demonstration was https://github.com/easrng/scratch-link-exploit which can automatically download and decrypt the key.

easrng commented 2 years ago

Note that this doesn't require local code execution to exploit. If you can intercept DNS then whenever users try to connect with Scratch Link you get their session ID and CSRF token.

arivero commented 2 years ago

So this is high severity, is it? Or is there a workaround to allow the revoked certificate? I guess one could extract it, with the hack, and add to the chain locally.

EDIT: ok, I see, it is not high severity because local users can always go to the keychain (at least in OSX) and give trust to a revoked certificate. Not sure which is the workaround for linux and windows, but I guess there is a similar one.

easrng commented 2 years ago

@arivero This is high severity because it means using any Scratch-link-requiring project on an untrusted network could result in your account being taken over.

cwillisf commented 2 years ago

Hi everyone! Thanks for your efforts in investigating this security issue.

First off: in the interest of keeping our users safe I would appreciate if you could contact us directly, at least initially, about vulnerabilities and exploits in the future. This kind of approach is sometimes called "responsible disclosure" or "coordinated vulnerability disclosure."

We just had a meeting to discuss what to do about this report, including the session token issue. We now have a plan, but it's going to take some time to implement the full solution. The current plan is:

  1. Very Soon: release a new version of Scratch Link which uses basically the same approach as the current release, but with two important differences. The new version will:
    • protect the sensitive info in a slightly different way
    • eliminate the session takeover vulnerability
  2. Soonish: release "Scratch Link 2.0" which handles communication with Scratch in a way that doesn't involve distributing a shared certificate & key

I'd like to acknowledge that some or all of the people in this conversation are probably savvy enough to work around anything I do in that "Very Soon" step, so you could probably extract the key and submit it for revocation again. However, since this new release will also fix the session takeover vulnerability, I believe the risk to users will be much lower.

With that in mind I'd ask you to please hold off on revoking the new certificate. It's going to take some time to implement a proper fix, adjust Scratch to use it, and coordinate the release of these changes in a way that will "just work" for the majority of Scratch users. I hope we can let people use a partially-fixed "Scratch Link 1.x" in the meantime.

Thank you!

apple502j commented 2 years ago

@cwillisf Thanks for posting!

I'd like to ask a few questions regarding the issue:

  1. The issue was already publicly known at least back in March 2021, when a user posted the issue #191. Was this issue moved to private repository for further consideration, or was it just straight up deleted?
  2. Scratch Link program, as far as I can remember, is out-of-scope for the private bug reporting program. Should these be reported to that website, or should we use Contact Us?
cwillisf commented 2 years ago

Good questions!

  1. Issue #191 was moved to a private repository, as we usually do with security-sensitive issues. Honestly, this issue will probably move too, for the same reason, but I wanted to allow for some conversation first. I wish there was an easy way to leave a "this issue was moved" notification! It's a little tricky, though, since even the issue title contains sensitive information.
  2. Good news: Scratch Link is not out-of-scope! Feel free to report this kind of issue either way, whichever works best for you.
calerga commented 2 years ago

Two words to explain why I started this issue. I know that a "user" server with tls but without a fixed ip or dns is impractical. So when I noticed it's precisely what Scratch Link does, I knew something was fishy. I checked Sectigo's CP, they're very clear. The extreme ease to revoke anonymously a certificate "just" with the private key is also pretty revealing.

You're bound by your agreement with Sectigo, but you decided to ignore what came in the way of what you wanted to achieve, whatever the risks for Scratch users (or others, anybody can use your certificate for any https or wss localhost server). Responsible disclosure is about bugs. That's not the case here. I didn't know that the issue had already been discussed last year, but obviously it wasn't enough to make you reconsider your decision. Once the certificate was revoked, I assumed the risks were behind us. Actually I was too optimistic because Chrome doesn't care much.

I don't know the exact scope of the risks, which cookies are used, and compromised, by scratch.mit.edu, or mit.edu, or whatever; or how secure contexts for web pages could be abused. I'd rather trust Sectigo. Frankly, I don't know what to do with your request.

cwillisf commented 2 years ago

@calerga, I appreciate your concerns but I disagree with your risk assessment. I'd also like you to consider that I believe we're both on the same side here: we'd both, I assume, like Scratch users to be able to use Scratch with hardware devices, and we'd both like this to be possible without security risks.

I assure you that we've been looking for a solution to this problem since before Scratch Link was even launched. We've even consulted with other companies to try to find a solution. The fact of the matter is that no one we have talked to has offered a better solution. There are many "helper" programs out there which operate in the same way, in order to allow a website to do something that is otherwise not possible. In fact, I have a few such programs installed on my personal computer -- not because of my job or for research, but because they're part of the software that I use on a regular basis. For example, one of the most common video drivers for Windows ships with a helper application which, near as I can tell, works in pretty much the same way -- and that one runs in the background at all times!

This practice started around the time that browsers started deprecating the concept of a browser plugin, since that was the previous solution to this kind of need. While many companies are (perhaps understandably) cagey about the details, I believe this is currently the de facto standard approach right now because the typical browser security model simply doesn't offer many options. The biggest difference between those programs and Scratch Link is that we publish the source code for Scratch Link, which makes it much easier to notice the issue.

For us it comes down to balancing risk vs. reward, from the perspective of a Scratch Link user. All the attack vectors we've identified, including the ones discussed on this issue and the previous issue, require that your computer and/or your network (specifically, DNS) are already compromised. If that's the case then you could be facing all sorts of problems, and taking over your Scratch account is relatively easy even if Scratch Link isn't in the picture. The overall risk of such a situation is high, but as I see it the risk increase due to Scratch Link working in this way is small. On the other hand, the "reward" of Scratch Link's current form is that it's working today, and allowing people to use Scratch with hardware devices in a way that's not possible without Scratch Link or an equivalent. Or, at least, it's working today for people whose operating systems and/or browsers have not yet downloaded the latest certificate revocation lists. Because in our view the rewards far outweighed the risks, we felt we could take our time looking for the best, safest, most-correct solution to the certificate problem. Now, it seems we should implement the first one that we can get working, and do so in a hurry.

If you have suggestions for a solution I'd welcome them! The previous report from @easrng made two suggestions, focusing on alternative communication protocols. Unfortunately the simpler of the two suggestions didn't work out, but the more complicated one, still under investigation, might turn out to be a solution.

It's clear that you feel strongly about this and that you care deeply about following best practices. From where you sit it probably looks like I don't, but I promise that's just because you don't have the meeting notes and discussion history from the Scratch Team's internal conversations about this issue. I can only ask for your understanding. I'm trying here; this is a truly hard problem.

calerga commented 2 years ago

@cwillisf, I understand very well that the situation is difficult. Any alternative giving the same functionality to Scratch users (transparent connection to Bluetooth devices from all major browsers) cannot be implemented in a hurry. Some ideas you could consider: serving everything, Scratch included, from a plain local http/ws/proxy server; using a WebRTC data connection between Scratch and Scratch Link; or using a relay server in the cloud with a suitable protocol.

Probably all of them have drawbacks you don't like. But where I fundamentally disagree, it's that distributing your private key, even if obfuscated, was ok. This isn't how tls is supposed to work. Ultimately, if what you want to do is impossible, so be it.

You are not alone, that's right. But other certificates have been revoked for the same reason. See e.g. https://www.feistyduck.com/bulletproof-tls-newsletter/issue_29_cisco_and_spotify_ship_private_keys_in_applications.

petrusek commented 2 years ago

I agree that this really is a hard problem to solve... I don't know what the other (more complicated) suggestion was, but since you asked (@cwillisf), I might have one suggestion too. To use WebBLE. I know it is not a solution to Scratch Link's problem, but it could be a solution how to enable your users to connect BLE devices to Scratch. WebBLE adoption is pretty good (IMHO) and maybe it could (at least partially) eliminate the need for Scratch Link.

easrng commented 2 years ago

WebBLE adoption is pretty good

WebBLE is only available in Chromium-based browsers.

As for communication methods, most browsers treat localhost as secure, so that might work. I assume you tried that though. Another solution is Native Messaging with a browser extension, and yet another is the WebRTC based one I remember suggesting last time. Probably the ideal solution would be native messaging where supported and maybe also WebRTC when not on a device/browser where native messaging is possible. (Using WebRTC could open up more possibilities for ex. using Scratch Link on one computer and running the project on another, which could potentially be helpful in places like a lab with mostly desktop computers without Bluetooth, and could open up possibilities for things like using a phone's sensors over Scratch Link by just scanning a QR code.)

calerga commented 2 years ago

@easrng Yes, the simplest solution would be plain http to 127.0.0.1 (I mean just for Bluetooth support via a new Scratch Link, keeping Scratch served from the cloud via https). WebRTC is nice in theory, difficult in practice (huge heap of protocols, few implementations, helping servers required...)

arivero commented 2 years ago

A fascinating, and anomalous IMHO, thing of the https architecture is that localhost needs a signed certificate at all. And that it does not come by default in the OS. Or wait, is it that you can not use localhost because CORS problems?

Because if CORS problems can be circumvented, a simple solution could be to allow to enter the scratch link domain name (making sure that it points to 127.0.0.1 and that it does not hear foreign tcp connections) and port both in scratch configuration and in scratch-link configuration. But

arivero commented 2 years ago

As for revocations, it you think they will keep happening, then perhaps in the documentation it should be explained how to revalidate locally a revoked certificate. It can still be done in OSX, and they are paranoid about this kind of things, so I would expect that it can be also done it Win and Linux.

easrng commented 2 years ago

A fascinating, and anomalous IMHO, thing of the https architecture is that localhost needs a signed certificate at all.

It doesn't. Serve a file containing

<script>alert(window.isSecureContext)</script>

then load it from a localhost web server. Loading it as http://localhost/ alerts true, so does http://127.0.0.x/, but oddly not http://[::]/.

colbygk commented 2 years ago

@easrng It does require HTTPS because if it is HTTP that mixes schema types on the same webpage, which, will not be allowed by the web browser due to the same-origin policy.

apple502j commented 2 years ago

@colbygk In newer browsers, 127.0.0.1 is exempt from mixed content restriction. (Not same-origin policy; WebSocket is not restricted by SOP.) See https://github.com/LLK/scratch-link/issues/137#issuecomment-772918857

The problem is that we need to drop Safari support if we use this approach.

colbygk commented 2 years ago

@apple502j Part of our basic principles are to work with the devices and software that are in folks' hands, not the ones that we want/hope they have in their hands. With major browsers not supporting mixed schema use on localhost, this potentially excludes a very large part of the potential user base.

Put another way, we are skating to where the hockey puck is going to be, not where we want it to be.

easrng commented 2 years ago

Another solution would be issuing certs per-device with letsencrypt and the dns01 challenge.

colbygk commented 2 years ago

@easrng Possibly, when I explored this last year, letsencrypt would throttle the ability to re-issue certs and complicate the issue. Also, DNS01 challenge resolution would require that the clients somehow have the ability to update the DNS information themselves which would require a much higher lift and would also be quite brittle.

calerga commented 2 years ago

@easrng But then the server must have a name and be reached from the outside. You'd need dns and often nat traversal. Many Scratch users don't have that. Maybe for the dns, Scratch could provide a dynamic solution which doesn't require any configuration from the user. But nat traversal is complicated to configure and risky, and probably not possible on mobile networks.

colbygk commented 2 years ago

@easrng Also, these all require having a working internet connection, something we cannot assume as there is a large proportion of the user base using the offline electron based application and scratch-link.

calerga commented 2 years ago

@colbygk If Scratch is local like in electron, you could skip completely tls (http and ws everywhere, no mixed content).

colbygk commented 2 years ago

@calerga That is true, but this is also multiplying support issues that can make it more difficult to deliver working software to end users. If the pathway to getting to scratch-link differs on a per platform basis, this adds complication that can lead to other issues that are just best avoided entirely.

It is very important to keep all of these issues in mind rather than focusing on one aspect of how we are making that communication work.

One option we're currently exploring is to have a different domain entirely, but that may also run afoul of SOP issues.

easrng commented 2 years ago

One option we're currently exploring is to have a different domain entirely, but that may also run afoul of SOP issues.

SOP is not an issue when you control the server, just add CORS headers.

cwillisf commented 2 years ago

For folks currently having trouble running Scratch Link:

easrng commented 2 years ago

For Windows you can temporarily patch your computers with https://github.com/easrng/scratch-link-fixer (It would be easy to port to Mac but I don't have a Mac so I can't do it rn)

BrickEducation commented 2 years ago

A good alternative is here https://www.brickeducation.it/scratchlink-non-funziona/

easrng commented 2 years ago

@BrickEducation That only works in Chrome, my patcher works on pretty much any browser except Safari.

BrickEducation commented 2 years ago

@BrickEducation That only works in Chrome, my patcher works on pretty much any browser except Safari.

You don't need to run Scratchlink to play with micro:bit or BLE (WEDO2) devices when your browser is Chrome, Edge or 'Web Bluetooth API' supporting one (the browser in Chromebook, Scrub in iPad, like that).

The Xcratch editor is a PWA (Progressive Web Apps), which means that once you access it, you can use it without any further Internet communication. You can also install it on your local machine if necessary.