4 Replies Latest reply on May 23, 2014 9:31 AM by Pierre Timmermans

    DTD, external entities and security

    Pierre Timmermans

      Hi,

       

      We had a security audit of our application, and the security people said we have to disable the use of the external entities in the XML parser. They say it is a vulnerability (even though they were not able to exploit that vulnerability to access some useful resource).

       

      I understand that the basis use case is when someone would add a DTD section in the XML submitted to the application and the DTD section would force the parser to resolve external entities, towards URL's or files for example. Although I think that for files there is no risk unless the file is in a directory authorized via a directory in the DB I think). A basic example would be

       

      <!DOCTYPE foo[

      <!ELEMENT foo ANY>

      <!ENTITY test SYSTEM 'file:///etc/passwd'>

      ]>

      <foo>

      &test;

      </foo>

       

      I was searching for a way to disable the use of external entities at the most global level possible, but could not find any way to do that.

       

      It is not very clear for me what is the use case in which such an attack could occur, but apparrently simply parsing a XML with a DTD and external entities is enough to be vulnerable, so for example if we use a XMLTYPE constructor with an input that is not checked against the existence of a DTD section we would be at risk ?

       

      Can anyone tell me what is the best way to protect our application ? What makes it difficult is that we run the application on Oracle 10 and on Oracle 12c

       

      Thanks and regards,

       

      Pierre

        • 1. Re: DTD, external entities and security
          Marco Gralike

          Outside the database, this might be a problem, although I think far fetched when using official DTD's and XML Schema's like "http://www.w3.org/2001/XMLSchema"

           

          Inside the database, using XMLDB functionality, you don't have the security problem (as described) and/or can be avoided:

           

          • The XMLDB functionality registers XSD and DTD's only in the database
          • Even references like http://www.w3.org/2001/XMLSchema are registered IN the database
          • References or calls outside the database to DTD's and/or XSD not registered in the database, ARE NOT allowed
          • DTD's, XSD's can only be registered in XMLDB (the database) by users who have the needed privileges
          • XML Schema's (and DTD's) are internally protected via a ACL security implementation (underneath Oracle uses Oracle Virtual Private Database functionality), So even (by default, without some "hacking" measures) people with roles like "DBA" can not see, read the registered XSD's / DTD's or alter them.

           

          ...

           

          HTH

          • 2. Re: DTD, external entities and security
            Pierre Timmermans

            Thanks for the reply, but there is still a problem I think in the case that the DTD is defined in-line, in the XML. If you pass such a XML to the Oracle parser, for example via the PL/SQL XMLTYPE constructor function, then Oracle will parse the XML and resolve the entities (maybe not the external entities).

            In our application, a procedure is called with as varchar2 parameter a XML string, then the application use XMLType on the parameter but without any validation of the input. I wonder if doing a XMLType only implies a parse of the string and so a vulnerability.

             

            Here is a sample that highltight the risk

            set define off
            set serveroutput on size 100000
            declare
             myStr varchar2(4000) := '
            <!DOCTYPE foo[
            <!ELEMENT foo ANY>
            <!ENTITY test "pierre">
            ]>
            <foo>
            &test;
            </foo>';
             myXML XMLType;
             myRes varchar2(4000);
            begin
              myXML := xmltype(myStr);
              insert into test(x) values(myXML);
              select myXML.getclobVal() into myRes from dual;
              dbms_output.put_line(myres);
            end;
            /
            -- with this select I will get <foo>pierre</foo>, it shows the entity was resolved
            select * from test;
            

             

            So the XML is parsed and stored in the database (as a XMLType column), and when I fetched it back I can see that the entity declared in the DTD was resolved. I think it happened when I inserted the string in the DB, not when the XMLType constructor was called.

             

            You will see that the entity test was replaced by the value "pierre". I am not sure this is a risk though, resolving external entities is not working (like file:///etc/password for example) and even if it was working I don't know how the hacker could get the data back (I don't understand why parsing only is a risk, according to the security company that did the assessment)

             

            What I tried to fix the problem is to check the XML against an XSD, using a parameter of the XMLTYPE constructor function. However, the oracle user owning the schema is version enabled and it is not working to generate an XSD in this case (I spend some time and could not find ways around this issue : because the user is version enabled he cannot create a table that depends on types from the same schema)

             

            In any case for the answer and the explanation

             

            Rgds, Pierre

            • 3. Re: DTD, external entities and security
              odie_63

              Hi Pierre,

              You will see that the entity test was replaced by the value "pierre". I am not sure this is a risk though, resolving external entities is not working (like file:///etc/password for example) and even if it was working I don't know how the hacker could get the data back (I don't understand why parsing only is a risk, according to the security company that did the assessment)

              There's no vulnerability at all in this example.

              There's no external entity defined, and even though there were some, XML DB forbids access to external resources, it only allows it for DTD residing in the repository.

              • 4. Re: DTD, external entities and security
                Pierre Timmermans

                Hi,

                I agree that there is no vulnerability in this case, no external resources are accessed. And indeed, when I try to access external resources it is not working

                 

                However the DTD does not reside in the repository, it is defined in-line, and so it can be injected easily by a hacker. What I would like is to forbid the use of in-line DTD, but I did not find something.

                 

                I think the solution I must force our developpers to implement is to validate the XML against a dtd and make sure that the validation schema forbid doctype declaration. It is complex though because of this version enabled feature : the xml schema generation is giving me headache :-)

                 

                Thanks