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
CVE-2021-41037: p2 metadata (even without artifacts) can be an attack vector #235
Comments
So one should only install from untrusted remote sites? :-) I think we should maybe better use some kind of term like "unknown" or "arbitrary" or something like that, because I assume that whenever I add something I first think it is good (and I trust it), so the outcome here is more that something unexpected happens e.g. never used that site before so do a double verification, the site include other sites from a different host and so on...
Should this not already be handled by the Certificate Trust settings? Maybe one should then change those to not include the root certificates but only explicitly user listed one (P2 can use a separate trust store for this). I think about this a bit similar to how SSH + know hosts work, whenever I connect to a new host I'm getting asked if that's fine and I should check the fingerprints and when something changes get a big fat warning (like recently with github). On the long run, and to support mirroring, XML Signatures are a well established standard, this also supports signing parts of the content (e.g. a single IU), and yes we need to upgrade the tools and stop using ancient update-sites, but the sooner the better... with eclipse simrel there is actually no excuse not using the latest IDE and updates, if users choose to use older (less secure) stuff this should not hinder making it safer for other. |
|
One idea would be that maybe additionally one wants to ask for confirmation when a touchpoint is executed. For example the |
No good post is complete without stating the exact opposite of what is intended. 😝 Yes, this needs to be carefully, and succinctly worded. I would also want to have a help tray description with a much longer description describing the concerns of touchpoints. What I'm trying to establish is that if we prompt the user with information about the source of the content they are installing, then we have addressed the stated problem of the CVE....
I don't know if the signing certificate for jar signing is the same one as is used for the https host. Even if it is the same, I would still like to present such information about the hosts involved with explicit request to trust the things coming from each specific host. I just want to be sure we provide good information to 'identify' the host.
Yes, we all saw that just recently! But I don't know what that fingerprint means, how I could compute/fetch such a thing, and what a user (I) can really do to verify it. The known_hosts file doesn't not show such a fingerprint...
I'd like to avoid going down what I perceive as a rabbit hole because it will be a very long time before we get to the end of that tunnel. I'm sure the discussion will be long, involved, and super interesting, though I question what actual value a perfect solution would provide; anyone will be able to do this with their IUs and their sites, so we'd still need to prompt for something, if not for the site/host, then for something else of an analogous nature, i.e., something else that certifies the origin of content... In any case, even if we (and I use the term we loosely) want to go down such a tunnel, I personally would still rather do something that addresses the stated problem in the very next release, without everyone else needing to do new-and-improved thing; as we saw in the last SimRel release cycle, coordinating multiple gson versions is already a stretch goal we barely managed.
You saw the long list of touchpoint information above?! That's just the touchpoints associated with IUs without artifacts when installing the absolute smallest application you can install; the I-can't-do-anything application. This is deeply technical information, there is a lot of it, and it is represented in a rather unstructured way. It is not something, in my opinion, that we ought to present to the user (because they won't understand it), nor should we try to analyze it deeply for potential problems, given that this framework is extensible and that "meta-requirements" can involve extending the framework to install additional touchpoint implementations that we won't understand at all. I think this too boils down to your observation that if I can get a user to install something that will add repositories that point to malicious things from which I can later try to get them to install yet more things, then I can already easily get them to install malicious things in the first place. I think informing users about the origin their content, providing information about that origin, and ensuring that the user is comfortable installing content from that origin addresses the stated problem, and is better than what we currently have. |
Usually a certificate has a certain role eg, it could be a used for signing other certificate, signing code or identifying a host: But technically they are all the same and therefore there is no distinction when it comes to the trust.
You usually compare them against a public second source of information e.g. See also here for other different techniques: https://www.phcomp.co.uk/Tutorials/Unix-And-Linux/ssh-check-server-fingerprint.html For certificates you usually can show even more information, but these are only informal, you can create a certificate with literally any information you like, so also there you usually need a second source e.g. https://www.digicert.com/kb/digicert-root-certificates.htm
Not everything in that list is really critical, that's why I picked one that is both a possible source of intrusion (adding new sites that are contacted due update) and usually well understood by the user. Most of the presented things will also most of the time only apply when creating a product (all those
Security comes at a cost, and usually inventing own schemes lead to security problems, the original CVE talks about that meta-data is an attack-vector, I can hardly image how this can be solved on the protocol level and you already have mentioned the problems of mirroring and local storage of that information, so I think we have two possible options:
|
|
To repeat myself succinctly, the CVE says exactly this:
I propose to inform the user about the source of the things they are installing such that the user can make an informed decision about whether to trust that source. No invention is required. It's a pragmatic approach to address an open problem for which no one else has plans to address. This approach does not preclude someone else building some alternative and better security mechanism(s) in the future. Of course if most people feel that problem is of low priority because the problem is much reduced by the enforced use of https, then doing nothing at all is an even simpler and definitely cheaper option. It's the option we've opted for to date... |
The location of the download to not tell anything about the source or if one can trust it, I already mentioned it on the bugzilla we have two domains (and these are not theoretical):
both have a valid SSL certificate that a usual system configuration will assume as "trusted", and even if you would ask the user how can one decide from just that that it is safe / trustful to execute potentially dangerous install instructions? So the CVE is talking about two things:
it does nowhere says that it is not possible for a user to understand that "something" is installed from a given location. Beside that the CVE explicitly list the bugzilla as a reference source, so picking out only a part of the CVE text that you think matches your argumentation is at least arguable. |
|
The Bugzilla too says "So they may install malicious code without any warning." The Bugzilla proposes one possible solution to that problem; the CVE does no propose a solution. In any case, both are focused on prompts and warnings such that the user is informed and can make informed trust decisions, so I don't feel I'm splitting hairs or taking one sentence out of context to alter its contextual meaning. When I'm in a browser and I enter my credit card details to buy something that originates from that supplier, the host name that I see in the bar is exactly where I expect my money will be going and is precisely how I decide whether or not I should be entering such highly-sensitive information in the entry fields and sending it out into the internet. So it's unclear to me why you feel that such information about the origin of the metadata does not provide identical information for making an informed decision about metadata origin. I don't propose to trust eclipse.de's metadata merely because the host supports https and has a proper certificate (as we currently "blindly" trust jar-signed artifacts merely because they are signed with a rooted certificate), but rather I propose to prompt for approval for IUs originating from any such host. Such prompting also helps with "blindly" trusting jar-signed content, which, as you've pointed out, is a very cheap and easy attack vector. |
|
I wanted to share some screen shots of the almost-complete prototype. Here's we're install this really messy thing. It brings up a trust dialog like this: This information is gathered during the collect phase, before any artifacts are downloaded. It does a full analysis of the origin of all installable units about to be installed, including following composite children and repository references (as in the epsilon repository for the above example) and also determining all the artifact repositories from which artifacts will be downloaded to produce the tree view of sites that you see above. For secured authorities, it shows the certificate chain of the SSL connection. Selecting an authority or site shows which IUs come from that site. Similarly selecting an IU shows from which sites that IU originates. (Just like in the Trust prompt dialog for artifact signers.) The user can review the details of each IU or select all IUs to see touchpoint information about them. There are preferences to manage the trusted authority URIs: This approach provides an additional level of security that we don't currently have. In particular, no user will "blindly" install some arbitrary-but-jar-signed artifact, from some arbitrary-but-https-secure host, without knowing they are installing content from that source. Hopefully I'll have PR ready tomorrow... |
|
@merks : while seeing the dialog with "what would be changed" I wonder if the content shown really belongs to spotbugs bundle? I've just checked and can't see where we are supposed to configure JVM arguments via p2 instructions but found nothing: https://github.com/search?q=repo%3Aspotbugs%2Fspotbugs%20xmx&type=code I'm also unaware that we ever added xmx argument to Eclipse via p2 instructions. May be this is done automatically by some maven/gradle task, but then it would be wrong anyway because Xmx value of 512m is/was not sufficient for any reasonable project size. So I assume the instructions do not belong to spotbugs and with that are shown wrongly in the dialog above. |
|
A Platform SDK IDE with everything in it is quite helpful for searching: Small values seem quite popular, probably from the old days of 32 bit JVMs... But we digress from the topic of this issue.... |
Not really. As a user of the dialog above I was scared by the "fact" that spotbugs would set my heap to 512m, which is not the case at all. So the dialog confuses me (spotbugs and platform committer) => it will for sure confuse people and they will start reporting bugs for spotbugs that we set some strange JVM arguments (which we don't do). |
|
I see your point of confusion! (Just as I didn't get that spotbugs == findbugs from your comment.) I did a select all and I am showing details... of all IUs. Moreover, I scrolled down to this one as you can see in the scroll bar on the side: But that's more clear when interacting with it than when seeing a static screen shot and not knowing how one got there... The takeaway I take is that I shouldn't show the one IU ID in the title if I'm actually showing hundreds of IUs; originally I only showed one IU's details but that seemed painful for reviewing hundreds quickly... |
|
Yep. |
|
This looks good overall to me. I have one concern and that is the scoping of trust at the site level. I went through a number of the most recently update marketplace entries and here are some that would make it questionable to trust the whole domain:
Some entries "do it right" like this: But that entry causes another site to be added as a reference repo that has similar issues of trusting domains only: Is this something you have already considered in your design? |
|
I figured that if one doesn't trust an entire domain one can simply not remember the one-time trust and just be prompted each time for things from that domain. But certainly more flexible is being able to trust subtrees of a domain, especially for places where multiple "organizations" host contents. But showing entire deeply nested subtrees really complicated the view and made it more complicated and more confusing to use, so I tried an approach of showing just one additional nesting level in the tree... So here I did an expand-all and a select-all: The selects-all checks all second level tree nodes and selecting any such node selects all its sub-nodes. I added some of the other examples/sites you mentioned. Note that while https://de-jcup.github.io/update-site-eclipse-bash-editor/update-site specifies a reference to https://dl.bintray.com/de-jcup/basheditor that reference isn't enabled so isn't loaded and hence not present in the above view. The preferences records these things: One can manually add trust for deep subtrees if that is desired as I did here, removing https://download.eclipse.org/modeling/ first: Then I would still get prompted for GMF but not for EMF: If I trust an entire domain, the trusted subtrees of that domain are removed because they are redundant then: What do you think? For multiple selection I now show this in the details: |
|
@merks That certainly addresses my concern. I also agree, your presentation of just one level looks good and addresses all the known cases in a clear to read way. |
Thanks. |
Tracking tracking is provided by ProvisioningContext's getInstallableUnitSources and getArtifactSources which do a deep analysis of all repositories, including children of composites and repository reference to track installable units and artifact keys back to their originating repository. This is used during the Engine's Collect phase as implemented by the new AuthorityChecker, which also manages underlying preferences for keeping track of trusted authorities. IInstallableUnitUIServices provide support for prompting the user and is implemented by ValidationDialogServiceUI to display TrustAuthorityDialog which is very similar in design to TrustCertificateDialog. The TrustPreferencePage is enhanced to provide user-level access to the trusted authorities preferences. eclipse-equinox#235
Tracking tracking is provided by ProvisioningContext's getInstallableUnitSources and getArtifactSources which do a deep analysis of all repositories, including children of composites and repository reference to track installable units and artifact keys back to their originating repository. This is used during the Engine's Collect phase as implemented by the new AuthorityChecker, which also manages underlying preferences for keeping track of trusted authorities. IInstallableUnitUIServices provide support for prompting the user and is implemented by ValidationDialogServiceUI to display TrustAuthorityDialog which is very similar in design to TrustCertificateDialog. The TrustPreferencePage is enhanced to provide user-level access to the trusted authorities preferences. eclipse-equinox#235
Also update the TrustCertificateDialog to better reflect the current implementation, to properly open the trust preferences and to cross reference the new help page. eclipse-equinox/p2#235
Tracking tracking is provided by ProvisioningContext's getInstallableUnitSources and getArtifactSources which do a deep analysis of all repositories, including children of composites and repository references to track installable units and artifact keys back to their originating repositories. This is used during the Engine's Collect phase as implemented by the new AuthorityChecker, which also manages underlying preferences for keeping track of trusted authorities. IInstallableUnitUIServices provide support for prompting the user and is implemented by ValidationDialogServiceUI to display TrustAuthorityDialog which is very similar in design to TrustCertificateDialog. The TrustPreferencePage is enhanced to provide user-level access to the trusted authorities preferences. #235
Also update the TrustCertificateDialog to better reflect the current implementation, to properly open the trust preferences and to cross reference the new help page. eclipse-equinox/p2#235
|
With the N&N details https://www.eclipse.org/eclipse/news/4.28/platform.php#trusted-authorities I've completed this effort. |












This issue's description and proposed remediation will be edited as this issue evolves. It is currently a draft work in progress.
Background:
The CVE has this description:
The bugzilla has description:
One thing seems clear up front. The oceans will need to significantly heat up before all p2 metadata will be properly and consistently signed and before the frameworks will properly check that. Often there can be a content.xml, content.jar, and/or content.xml.xz, all of which will need to be signed, though they typically contain (and should contain) the same semantic content. As such, all the ways of building these would need to produce such signatures and all such signatures would need to follow the artifact (metadata files) that they sign, e.g., the various of mirror applications and scripts would need to be aware of these new things, often needing to resign the resulting content. And finally, the consuming applications would all need to have installed a framework that checks these signatures. The whole ecosystem would need to support producing such things, not just Eclipse projects, i.e., those project with enough resource to deal with the associated workload. It seems to me like a giant hurdle, and then the actual concrete benefit versus the cost is questionable at best.
We are circling around a topic for which there is a confusing and misleading mixture between related, yet different concepts, i.e., certification of origin, security, and trust. We can very easily install something from a known/certified source, via a secure connection that is nevertheless completely untrustworthy. As Christoph has pointed out, it's very easy to buy a signing certificate, get a free PGP signing key, and to provide content on an https accessible host, i.e., it's very, very easy to provide horribly malicious code. That would continue to be the case even if p2 metadata were signed. While it's suggested that signed artifacts are provided for trust, that's only indirectly/transitively the case; they are provided as a certification of origin, and one can choose to trust that origin. They have the added benefit that the certification follows the actual artifact.
Here's a simple example of IUs that get installed that have touchpoints but no artifacts, and hence will not result in a trust prompt for certificates or PGP keys:
unconfigure=setProgramProperty(propName:osgi.instance.area.default,propValue:);configure=setProgramProperty(propName:osgi.instance.area.default,propValue:@user.home/workspace);unconfigure=removeProgramArg(programArg:--launcher.library);removeProgramArg(programArg:@artifact);uninstall=uninstallBundle(bundle:${artifact})configure=addProgramArg(programArg:--launcher.library);addProgramArg(programArg:@artifact);install=installBundle(bundle:${artifact})unconfigure=setProgramProperty(propName:eclipse.product,propValue:);setProgramProperty(propName:osgi.splashPath,propValue:);setProgramProperty(propName:osgi.bundles.defaultStartLevel,propValue:);setProgramProperty(propName:eclipse.application,propValue:);setProgramProperty(propName:eclipse.buildId,propValue:);configure=setProgramProperty(propName:eclipse.product,propValue:org.eclipse.platform.ide);setProgramProperty(propName:osgi.splashPath,propValue:platform${#58}/base/plugins/org.eclipse.platform);setProgramProperty(propName:osgi.bundles.defaultStartLevel,propValue:4);setProgramProperty(propName:eclipse.application,propValue:org.eclipse.ui.ide.workbench);setProgramProperty(propName:eclipse.buildId,propValue:4.27.0.I20230302-0300);configure=addRepository(type:0,location:https${#58}//download.eclipse.org/eclipse/updates/4.27,name:The Eclipse Project Updates);addRepository(type:1,location:https${#58}//download.eclipse.org/eclipse/updates/4.27,name:The Eclipse Project Updates);addRepository(type:0,location:https${#58}//download.eclipse.org/releases/2023-03,name:2023-03);addRepository(type:1,location:https${#58}//download.eclipse.org/releases/2023-03,name:2023-03);mkdir(path:${installFolder}/dropins);uninstall=cleanupzip(source:@artifact, target:${installFolder});install=unzip(source:@artifact, target:${installFolder});unconfigure=removeProgramArg(programArg:-startup);removeProgramArg(programArg:@artifact);uninstall=uninstallBundle(bundle:${artifact})configure=addProgramArg(programArg:-startup);addProgramArg(programArg:@artifact);install=installBundle(bundle:${artifact})unconfigure=setStartLevel(startLevel:-1);markStarted(started: false);uninstall=uninstallBundle(bundle:${artifact})configure=setStartLevel(startLevel:2);markStarted(started: true);install=installBundle(bundle:${artifact})unconfigure=markStarted(started: false);uninstall=uninstallBundle(bundle:${artifact})configure=markStarted(started: true);install=installBundle(bundle:${artifact})unconfigure=setStartLevel(startLevel:-1);markStarted(started: false);uninstall=uninstallBundle(bundle:${artifact})configure=setStartLevel(startLevel:1);markStarted(started: true);install=installBundle(bundle:${artifact})unconfigure=setStartLevel(startLevel:-1);markStarted(started: false);uninstall=uninstallBundle(bundle:${artifact})configure=setStartLevel(startLevel:2);markStarted(started: true);install=installBundle(bundle:${artifact})unconfigure=setLauncherName()configure=setLauncherName(name:eclipse)unconfigure=removeJvmArg(jvmArg:-Dosgi.requiredJavaVersion=11);removeJvmArg(jvmArg:-Dosgi.dataAreaRequiresExplicitInit=true);removeJvmArg(jvmArg:-Dorg.eclipse.swt.graphics.Resource.reportNonDisposed=true);removeJvmArg(jvmArg:-Xms40m);removeJvmArg(jvmArg:-Xmx512m);removeJvmArg(jvmArg:--add-modules=ALL-SYSTEM);removeProgramArg(programArg:--launcher.defaultAction);removeProgramArg(programArg:openFile);removeProgramArg(programArg:--launcher.appendVmargs);configure=addJvmArg(jvmArg:-Dosgi.requiredJavaVersion=11);addJvmArg(jvmArg:-Dosgi.dataAreaRequiresExplicitInit=true);addJvmArg(jvmArg:-Dorg.eclipse.swt.graphics.Resource.reportNonDisposed=true);addJvmArg(jvmArg:-Xms40m);addJvmArg(jvmArg:-Xmx512m);addJvmArg(jvmArg:--add-modules=ALL-SYSTEM);addProgramArg(programArg:--launcher.defaultAction);addProgramArg(programArg:openFile);addProgramArg(programArg:--launcher.appendVmargs);uninstall=uninstallFeature(feature:${artifact},featureId:default,featureVersion:default)install=installFeature(feature:${artifact},featureId:default,featureVersion:default)unconfigure=markStarted(started: false);uninstall=uninstallBundle(bundle:${artifact})configure=markStarted(started: true);install=installBundle(bundle:${artifact})uninstall=removeSourceBundle(bundle:${artifact})install=addSourceBundle(bundle:${artifact})unconfigure=setStartLevel(startLevel:-1);markStarted(started: false);uninstall=uninstallBundle(bundle:${artifact})configure=setStartLevel(startLevel:2);markStarted(started: true);install=installBundle(bundle:${artifact})unconfigure=uninstall=uninstallBundle(bundle:${artifact})configure=setStartLevel(startLevel:4);install=installBundle(bundle:${artifact})We should note that even if the p2 metadata were signed, once these instructions are applied, their origin can no longer tracked afterwards, unlike for actual installed artifacts (jars).
I propose we take a step back and focus on what we can do to make this statement no longer true:
In particular I'd like to propose that when we install/update that we present the user with the list of the corresponding sites of the IUs they are adding as part of that install/update operation. With the changes from #230 we already ensure that the sites are accessed securely typically via https. We can present a message as follows:
We could even collect the certificate information from those hosts to present to the user (as we do for jar-signed content). With that additional information, the user can effectively determine the origin of the content. We can of course make it possible to remember the trusted hosts as we do for trusted PGP keys so the user is not repeated prompted for the same origins.
I feel that this approach provides the level of confirmation that the user needs to make informed decisions about what they are installing and where it's coming from. That approach makes the following statement accurate:
This approach can be implemented with minimal cost to the community while effectively giving the user both notification and control as spelled out in the CVE.
The text was updated successfully, but these errors were encountered: