Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to use <!ENTITY in ANDROID resources with error: "The entity was referenced, but not declared."

I'm following this solution to use enetities in my string resource file:

Is it possible to do string substitution in Android resource XML files directly?

I'm using an external file in the resource tree: /res/raw/entities.dtd, its content:

<!ENTITY ent_devicename "MyDeviceName">

In the string.xml resource file:

<!DOCTYPE resources [
    <!ENTITY % ent_devicename SYSTEM "../raw/entities.dtd">
    %ent_devicename;
]>

<resources>
    <string name="name">The name is &ent_devicename;</string>
</resources>

but I get this error:

The entity "ent_devicename" was referenced, but not declared.

As you can see Android Studio recognizes the external entity file:

enter image description here

and the entity:

enter image description here

Can someone provide full a correct example to make things work? I mean a full compilable Android Studio project, with entities declarations in a separated file.

UPDATE Ok, if you pay more attention to this w3schools link:

https://www.w3schools.com/xml/xml_dtd_entities.asp

you see the solution:

the external entities.dtd files contains

<!ENTITY ent_devicename "MyDeviceName">

then the new string resource resource:

<?xml version="1.0" encoding="utf-8"?>

    <!DOCTYPE resources [
        <!ENTITY ent_devicename SYSTEM "../raw/entities.dtd">
        ]>

<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="Typos">
    <string name="ent_devicenamxxe2">&ent_devicename;</string>

I changed <!ENTITY % ent_devicename to <!ENTITY ent_devicename (no more %) I deleted %ent_devicename;

Now it compiles but the resulting APK seems to ignore the entity values (uses an empty string). So the problem is not resolved!

Let me know!

like image 614
Seraphim's Avatar asked Jun 19 '18 17:06

Seraphim's


Video Answer


3 Answers

TL;DR This feature has been removed from Android Studio. See the bug report here.

It looks like XML External Entities were supported at one time in Android Studio. It also looks to me like Android Studio currently should be supporting external entities since the editor doesn't complain. The underlying processing of the XML doesn't actually do the inclusion as expected giving the "referenced but not declared" error.

Although I have not found an explicit reference to Android Studio abandoning external entities, it would make sense due to a vulnerability that was uncovered. See Android Developers Susceptible to Data Exposure from XXE Attack and the security write-up.

It is also possible that access to external entities are now gated somehow, but I think that Android Studio would be more helpful if that is the case. It is more likely that the functionality was just removed due to the vulnerability.

By the way, I have experimented with the other answers and I have had no luck - just the same error.

Edit:

I just came across a Medium post that discusses JetBrains addressing the XXE vulnerability.

Second edit

I found a reference for the disablement on the bug tracker.

this may have been disabled for security reason, it requires complete analysis before resolution, punting to 3.2

and

This was indeed disabled for security reasons (preventing XXE attacks) in Change-Id: I2f1978bc5458ba2b2b2d6ffbc9df5710c487a4e4.

It's status is "won't fix-intended behavior." It would have been nice if Studio had been changed to emit an error message that the facility was disabled for security reasons.

like image 56
Cheticamp Avatar answered Oct 18 '22 01:10

Cheticamp


There's a history of answers/comments to this question not helping you, so let's simplify and approach one step at a time. Please use the updated entity names I show below, and please use a single directory for both the XML file and the included entities file.

1. Establish that internal entity references are working.

string.xml

<!DOCTYPE resources [
  <!ENTITY devicename "MyDeviceName">
]>

<resources>
    <string name="name">The name is &devicename;</string>
</resources>

Verify that this works as expected: After applications parse this XML file, it should be equivalent to this XML file:

<resources>
    <string name="name">The name is MyDeviceName</string>
</resources>

Let me know explicitly in the comments whether you are able to get step 1 working.

2. Add the extra level of indirection, if needed.

entities.ent

<!ENTITY devicename "MyDeviceName">

string.xml

<!DOCTYPE resources [
    <!ENTITY % ext_entities SYSTEM "entities.ent">
    %ext_entities;
]>

<resources>
    <string name="name">The name is &devicename;</string>
</resources>

To an XML application that uses a conforming XML parser, string.xml will again be equivalent to

<resources>
    <string name="name">The name is MyDeviceName</string>
</resources>

and you will now be able to share the entities defined in entities.ent.

For this step I ask that you take care not to re-use the entity names for the internal and external entities and that you not add any complications due to different directory location; place both entities.ent and string.xml in the same directory. (This can be relaxed later once you establish the expected functionality.)

Again, let me know in the comments whether you are able to get step 2 working.

like image 2
kjhughes Avatar answered Oct 18 '22 01:10

kjhughes


I am afraid importing external entities is not possible (proof1,proof2). Here is the only way.

<?xml version="1.0"?>
<!DOCTYPE resources [
    <!ENTITY value_a "Value A">
    <!ENTITY value_b "Value B">
    ]>

<resources>
    <string name="app_name">&value_a;</string>
    <string name="app_settings ">&value_b;</string>
</resources>
like image 1
deadfish Avatar answered Oct 18 '22 00:10

deadfish