SonarLint reports many possible XXE attacks in eclipse IDE's sourcecode.
for example:
Steps to reproduce
Don't know. Probably manipulating development xml-files like "build.xml", "plugin.xml", "feature.xml", ".polyglot.feature.xml", ...
which should be normally self contained and do not require access from external sources.
For people added or a first time to a confidential issue: you need to be logged in in GitLab to see it, otherwise you will get a 404. I've added project leads for PDE, JDT, Eclipse Platform, and OSGI. If there are more people to add, please add me know. For now, it requires manual manipulations.
Can anyone comment on the bug fix https://bugs.eclipse.org/bugs/show_bug.cgi?id=577341 mentioned by @jkubitz which changed XMLMemento to add "file" to the properties: javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD and javax.xml.XMLConstants.ACCESS_EXTERNAL_SCHEMA? According to the spec, it recommends setting the properties to "" and I notice XMLMemento is showing up in the report. Is this a separate case or a false positive or should it be done as specified in https://rules.sonarsource.com/java/RSPEC-2755?
@jkubitz do you plan to contribute fixes for the issue?
At least for PDE it looks like the same pattern can be used for most, if not all occurrences. Therefore I think it makes sense to have a utility method that returns a properly configured DocumentBuilderFactory/XMLInputFactory.
Besides that, when searching PDE's code base for DocumentBuilderFactory.newInstance(), I got more hits than the listed ones, maybe this applies for other repos too.
When we agree it should be fixed in the sense to disallow all external xml references i could contribute something. I would like a solution where platform (runtime?) offers a configured parser.
Do we have any usecase where we need external files? If not let's disable all. Even "file", as Jeff mentioned.
At least for PDE I'm not aware of a use-case where external files are needed, but I haven't checked all cases.
I would also have started with a restrictive approach until hitting a point where this is not sufficient.
example stacktrace how jdt tries to open external file:
java.io.FileNotFoundException: c:\mysecret.txt (Das System kann die angegebene Datei nicht finden) at java.base/java.io.FileInputStream.open0(Native Method) at java.base/java.io.FileInputStream.open(FileInputStream.java:216) at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157) at java.base/java.io.FileInputStream.<init>(FileInputStream.java:111) at java.base/sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:86) at java.base/sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:189) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:653) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1397) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(XMLEntityManager.java:1363) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(XMLDTDScannerImpl.java:257) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1152) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1040) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:943) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:542) at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:889) at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825) at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1224) at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:637) at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:326) at java.xml/javax.xml.parsers.SAXParser.parse(SAXParser.java:330) at org.eclipse.jdt.core.tests.formatter.DecodeCodeFormatterPreferences.decodeCodeFormatterOptions(DecodeCodeFormatterPreferences.java:68) at org.eclipse.jdt.core.tests.formatter.FormatterRegressionTests._test749(FormatterRegressionTests.java:16229)
No, it is better to work on the fix privately. For that, we can assign the projects committers (or PL only) the "security manager" role on the github organization. With this permission, users with this role can create a security adivisory to discussing and working on the fix. The fix can be elaborated on a temporary private fork and then create a PR from the private fork. It's best to not mention anything about the vulnerability in the commit / PR comments, just focusing on the technical details. Once the fix is merged and release, you can add a comment to the changelog mentioning that a vulnerability has been fixed via PR-XXX and give details about the vulnerability. You can also give a CVE number if you've decided to assign one for the vulnerability.
To create a temporary fork for a security fix, it needs to be linked to security advisories. And currently it seems that security advisories are disabled for eclipse-platform. That might be a good occasion to enable them and also enable private reporting via GitHub (and take part in our GitHub pilot for private security advisories).
Please note that it does not disable the possibility to use the current methods - it just adds one more and some handy features for the project team.
Security advisories are already enabled (there is the "Security" tab on GitHub project page you can browse). However, I see in the doc
Who can use this featureAnyone with admin permissions to a repository, or with a security manager role within the repository, can create a security advisory.
I suspect that the maintainers (committers or project leads) misses to be assigned a "security manager" role, so at the moment, no-one can use the feature because of this missing permission.
When using self-service for your GitHub organization, you can request changes to the security managers for your organization via a configuration file. Take a look at the adoptium project which has the project leads defined as security managers (others have all committers):
However, a change like that will require an approval of one of the project leads of the jdt project.
When creating the PR can you add a project lead as reviewer?
Created PR https://github.com/eclipse-jdt/.eclipsefdn/pull/1 to enable committers as security managers. After it is approved and applied you can create security advisories. Alter reviewer as needed, I picked one project lead as the team is not public yet (we plan to make all teams public).
the process is to create PRs that will be approved and merged by EF staff. After being merged the changes will be applied to your live configuration at GitHub.
The CVE ID is reserved, but please do not use it publicly (this ticket is OK, because it is confidential) before you release a fix and we fill up all details of that CVE. If you need any assistance, contact me or @mbarbero
Victim only needs to refresh an already open project or open it. So basically as soon as you pull anything (for example to review PR) an remote server can read victims file system.
As background for others, we are looking for a place for a XMLProcessorFactory that provides factories for SAXParsers, DocumentBuilders ans Transformers that are configured to be not vulnerable for XXE attacks. Ideally there is only one such class used by all Eclipse SDK projects (Equinox, Platform, JDT and PDE), but is not API for downstream consumers. This probably has the effect that not all methods are called by projects in the repo that contains it, but IMHO it is more important to have a single location to maintain that multiple copies of it. And since all SDK projects are build in the I-Builds it would be noticed quickly if something changed in an incompatible way. Nevertheless the documentation of the class should state that callers can be all over the SDK.
Since Equinox and even org.eclipse.osgi needs a XMLProcessorFactory too, I suggest the package org.eclipse.osgi.framework.util as location for it. In general it I think it would be better to use a package that has internal in its name (org.eclipse.osgi.framework.util is only marked as internal in the Manifest), but I didn't found any fitting one. If we really want that, we could either create a new one like org.eclipse.osgi.internal.xml or place it in an existing one with a not so fitting name (I wouldn't mind much).
@twatson what do you think?
@hwellmannwr6 Why isn't the one place to update in org.eclipse.osgi.internal.framework.XMLParsingServiceFactory.createService() to return a factory properly configured? Everywhere else just use the OSGi service to get the properly configured factory.
Have to admit that I didn't think about that yet, but that would definitely be the most OSGi-like way.
This also reminds me about https://github.com/eclipse-equinox/equinox/pull/146, which would make it quite convenient to obtain a parser-factory. Would be a good reason for me to complete that.
But besides a SAXParserFactory and a DocumentBuilderFactory it would require also a service registration for TransformerFactory. Furthermore the PDEXmlProcessorFactory suggested in https://github.com/eclipse-pde/eclipse.pde/pull/667 also provides SAXParserFactorys with different levels of DOCTYPE rejection.
But this could be specified using service-attributes.
The framework registers a ServiceFactory for the SAXParserFactory and DocumentBuilderFactory so each bundle can individually configure the instance they get (e.g. what PDE needs for different levels of DOCTYPE rejection). We could change it to be a PrototypeServiceFactory so that a bundle can configure multiple factory instances if need be. But by default the factory we return would be auto configure to prevent the XXE. I'm unsure what uses TransformerFactory in Eclipse. But I would prefer not adding a new service registration down in the framework for that. Perhaps adding it to equinox.common or to core.runtime would be useful.
I don't see a real need for supporting entity for .project. Normally eclipse should write it and it won't write any entity. If we would support file resolution you could inject a local secret into the .project. And file is not even necessary local (if you have a remote filesystem mounted). The safest way is to just forbid anything if we don't need it. If there will be a usecase to need file resolution the user should contribute a safe way to do so. The only .xml files in eclipse that i know that normally used with file resolution are ant's build.xml scripts. For those it doesn't matter to parse the entity while executing the script because the script could do anything anyways. However it would be wrong to perfrom the resolution while only showing the script.
@netomi Github actions, like verification builds, are not executed in the private forks. That way we can not see if verification would fail. please help.
@jkubitz ok so I checked the workflows in the eclipse.jdt.core repo and I am not sure how useful it is to be able to run them. They seem to be related for release management and publishing unit test results.
In order to validate that the fixes in the eclipse.jdt.core-ghsa-794m-c7jj-3qxv repo are not breaking anything, somebody will have to setup a job on jenkins that checks out the clone and runs the build. I will check with my colleagues how we usually do that for eclipse-jdt.