-
Notifications
You must be signed in to change notification settings - Fork 48
Description
This issue's description and proposed remediation will be edited as this issue evolves. It is currently a draft work in progress.
Background:
- https://bugs.eclipse.org/bugs/show_bug.cgi?id=577029
- https://nvd.nist.gov/vuln/detail/CVE-2021-41037
The CVE has this description:
In Eclipse p2, installable units are able to alter the Eclipse Platform installation and the local machine via touchpoints during installation. Those touchpoints can, for example, alter the command-line used to start the application, injecting things like agent or other settings that usually require particular attention in term of security. Although p2 has built-in strategies to ensure artifacts are signed and then to help establish trust, there is no such strategy for the metadata part that does configure such touchpoints. As a result, it's possible to install a unit that will run malicious code during installation without user receiving any warning about this installation step being risky when coming from untrusted source.
The bugzilla has description:
p2 metadata, even without artifacts, can affect the application in unsafe way: touchpoints can run some local commands, change the command line that will be used to start the IDE (ie changing the JVM, adding some agents...). It seems relatively easy to inject malicious changes in p2 metadata.
Unlike artifacts, installing a unit that consists only of metadata doesn't show any warning to users. So they may install malicious code without any warning. There is no concept of "trusting" metadata like it exists for artifacts.On the long run, the solution would be to sign metadata as well, like other package managers -eg rpm- do.
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:
- toolingorg.eclipse.platform.configuration 1.0.0
unconfigure=setProgramProperty(propName:osgi.instance.area.default,propValue:);
configure=setProgramProperty(propName:osgi.instance.area.default,propValue:@user.home/workspace);
- toolingorg.eclipse.equinox.launcher.win32.win32.x86_64 1.2.700.v20221108-1024
unconfigure=removeProgramArg(programArg:--launcher.library);removeProgramArg(programArg:@artifact);
uninstall=uninstallBundle(bundle:${artifact})
configure=addProgramArg(programArg:--launcher.library);addProgramArg(programArg:@artifact);
install=installBundle(bundle:${artifact})
- toolingorg.eclipse.platform.ide.config.win32.win32.x86_64 4.27.0.I20230302-0300
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);
- org.eclipse.platform.ide 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);
- toolingorg.eclipse.platform.ide.executable.win32.win32.x86_64 4.27.0.I20230302-0300
uninstall=cleanupzip(source:@artifact, target:${installFolder});
install=unzip(source:@artifact, target:${installFolder});
- toolingorg.eclipse.equinox.launcher 1.6.400.v20210924-0641
unconfigure=removeProgramArg(programArg:-startup);removeProgramArg(programArg:@artifact);
uninstall=uninstallBundle(bundle:${artifact})
configure=addProgramArg(programArg:-startup);addProgramArg(programArg:@artifact);
install=installBundle(bundle:${artifact})
- toolingwin32.win32.x86_64org.eclipse.equinox.common 4.27.0.I20230302-0300
unconfigure=setStartLevel(startLevel:-1);markStarted(started: false);
uninstall=uninstallBundle(bundle:${artifact})
configure=setStartLevel(startLevel:2);markStarted(started: true);
install=installBundle(bundle:${artifact})
- toolingwin32.win32.x86_64org.eclipse.core.runtime 4.27.0.I20230302-0300
unconfigure=markStarted(started: false);
uninstall=uninstallBundle(bundle:${artifact})
configure=markStarted(started: true);
install=installBundle(bundle:${artifact})
- toolingwin32.win32.x86_64org.eclipse.equinox.simpleconfigurator 4.27.0.I20230302-0300
unconfigure=setStartLevel(startLevel:-1);markStarted(started: false);
uninstall=uninstallBundle(bundle:${artifact})
configure=setStartLevel(startLevel:1);markStarted(started: true);
install=installBundle(bundle:${artifact})
- toolingwin32.win32.x86_64org.eclipse.equinox.event 4.27.0.I20230302-0300
unconfigure=setStartLevel(startLevel:-1);markStarted(started: false);
uninstall=uninstallBundle(bundle:${artifact})
configure=setStartLevel(startLevel:2);markStarted(started: true);
install=installBundle(bundle:${artifact})
- org.eclipse.platform.ide.executable.win32.win32.x86_64.eclipse 4.27.0.I20230302-0300
unconfigure=setLauncherName()
configure=setLauncherName(name:eclipse)
- toolingorg.eclipse.platform.ide.ini.win32.win32.x86_64 4.27.0.I20230302-0300
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);
- tooling.org.eclipse.update.feature.default 1.0.0
uninstall=uninstallFeature(feature:${artifact},featureId:default,featureVersion:default)
install=installFeature(feature:${artifact},featureId:default,featureVersion:default)
- toolingwin32.win32.x86_64org.eclipse.equinox.p2.reconciler.dropins 4.27.0.I20230302-0300
unconfigure=markStarted(started: false);
uninstall=uninstallBundle(bundle:${artifact})
configure=markStarted(started: true);
install=installBundle(bundle:${artifact})
- tooling.source.default 1.0.0
uninstall=removeSourceBundle(bundle:${artifact})
install=addSourceBundle(bundle:${artifact})
- toolingwin32.win32.x86_64org.apache.felix.scr 4.27.0.I20230302-0300
unconfigure=setStartLevel(startLevel:-1);markStarted(started: false);
uninstall=uninstallBundle(bundle:${artifact})
configure=setStartLevel(startLevel:2);markStarted(started: true);
install=installBundle(bundle:${artifact})
- tooling.osgi.bundle.default 1.0.0
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:
It's possible to install a unit that will run malicious code during installation without user receiving any warning about this installation step being risky when coming from untrusted source.
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:
Installing content from arbitrary remote sites is risky. Do you with to trust content from the follows hosts.
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:
Before the user installs any content, they will be warned about the risk of installing content from untrusted sources and they will be provided a list of the actual sources being used for their consideration and approval.
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.