Bug #67350 [Opn]: An XML DTD with an external parameter failes to include the subset

From: Date: Thu, 05 Jun 2014 02:09:18 +0000
Subject: Bug #67350 [Opn]: An XML DTD with an external parameter failes to include the subset
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-186061@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=67350&edit=1

 ID:                 67350
 User updated by:    rjlaustin at teksavvy dot com
 Reported by:        rjlaustin at teksavvy dot com
 Summary:            An XML DTD with an external parameter failes to
                     include the subset
 Status:             Open
 Type:               Bug
 Package:            DOM XML related
 Operating System:   Linux
 PHP Version:        5.4.28
 Block user comment: N
 Private report:     N

 New Comment:

Thanks once more. I looked at the libxml2 patch and it certainly seems as if it might be responsible
for the change, but I can't say I understand what this code is exactly testing, i.e. in what
circumstances it will return without doing anything.
++                    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
++		        ((ctxt->options & XML_PARSE_NOENT) == 0) &&
++			((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
++			(ctxt->validate == 0))
++			return;

Anyway, you seem to have found very strong evidence that the problem is located in libxml2 rather
than PHP itself.

So was the reason for my PHP code breaking on the two Linux systems, the patch to libxml2? The date
of the patch seems to be 8 May and you say it was included in systems built on the 15 May. The first
of my two users to report the problem, reported it on 20 May but their PHPINFO display says the
System is:
Linux gilly 3.11.0-19-generic #33-Ubuntu SMP Tue Mar 11 18:48:34 UTC 2014 x86_64
with a Build Date of:
Apr 4 2014 01:07:05
Could that patch be in libxml2 even though the build date and the system date are earlier than the
patch date? It seems rather unlikely but I suppose it could be ...

So if anyone wants to close this now, as far as I'm concerned they can.
I wish the documentation on the 'LIBXML_DTDLOAD' option was just a bit clearer.
And I wish PHP behaved the same on all platforms so we could at least be sure which was the right
behaviour.

But for anyone else who runs into the problem, obviously their first move should be to add the
'LIBXML_DTDLOAD' option to their load() or loadXML() call.

Thanks again for the explanations.


Previous Comments:
------------------------------------------------------------------------
[2014-06-04 19:24:43] ant-dani-2 at hotmail dot com

Ok, I get what you mean now.
1. I'm only using ubuntu 14.04 x64
2. I found out about the security patch through libxml2's page on ubuntu launchpad (took some
time to correlate the events).
3. For all LTS versions of ubuntu, libxml2 received the patch on 2014-05-15
Source: https://launchpad.net/ubuntu/+source/libxml2

------------------------------------------------------------------------
[2014-06-04 13:43:30] rjlaustin at teksavvy dot com

Thank you. I don't really want to bother you further but I don't think you quite
understood my question about having evidence.

What I meant was: did you
(a) not have this problem on one version of Linux (say, version x)
(b) find that you DID get this problem on a newer version (say, version y)
(c) identify the security patch as being in version y and not in version x?

I cannot obtain this sort of evidence because I don't have the Linux system necessary to create
it.

Do you have an ID for the security patch you have been talking about?

------------------------------------------------------------------------
[2014-06-04 13:06:07] ant-dani-2 at hotmail dot com

If you look at http://uk.php.net/libxml.constants,
you'll see that LIBXML_DTDLOAD is described as "Load the external subset".
The "subset" is (as far as I know) any entity with an external DTD. DOCTYPE is the set.

And I can say I do have evidence.
I was trying to embed the XHTML 1.0 Transitional DTD, with the intent of having several (unique id)
HTML nodes that define different webpage layouts.
This would (and did) allow me to focus solely on the code behaviour, without my eyes bleeding from
seeing mixed PHP/HTML.

Everything was working fine on windows, but validation always failed on Linux.
Looked on Apache's error log, and saw warnings about "declaration not found for element
..."

The 'head' of my layout.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE layout [
<!ELEMENT layout (html?)>
<!ENTITY % html SYSTEM "xhtml/xhtml1-transitional.dtd">
%html;
]>

------------------------------------------------------------------------
[2014-06-03 15:10:56] rjlaustin at teksavvy dot com

Thanks. I should have looked up XXE (which meant nothing to me) which I have now done, and I have
read what the OWASP site has to say about the vulnerability.

Point 1. What I observe is this:
The PHP version 5.5.11 (April 9 2014) for the Mac, as distributed by XAMPP, allows access to an
external subset within a DTD WHETHER OR NOT the option LIBXML_DTDLOAD is used on the PHP function
call loadXML().

What I don't know is: is that good behaviour or bad behaviour?

If the purpose of the LIBXML_DTDLOAD option is to allow external file access, then I would have
expected that when that option is absent external file access should NOT be allowed. But that may
not be what LIBXML_DTDLOAD is supposed to do.

Point 2. What I also observed was this:
On the Linux systems that experienced the problem I reported, only the subset of the DTD was not
loaded; but the major file, the one named in the DOCTYPE element, was still being happily accessed.
The OWASP article on this XXE vulnerability deals exclusively with that access; it doesn't
mention the subset access that was what broke for me.

If the security patch that you identify as resulting in the behaviour on Linux that broke my code is
actually supposed to prevent access to external files named in the DOCTYPE element, it is NOT
working. It is allowing those files, but blocking (silently) only their subsets. Blocking subsets
while still allowing the main file to be read doesn't make sense to me.

Do you, by any chance, have evidence that the security patch of which you write was added to the
Linux build at the time when this bug (change in behaviour, if you prefer) first occurred?

------------------------------------------------------------------------
[2014-06-03 10:05:53] ant-dani-2 at hotmail dot com

Well, the problem on linux is allowing something like this
<!ENTITY % something SYSTEM "/etc/shadow">
let pass through the parser, specially if the web server is running as root.

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=67350


--
Edit this bug report at https://bugs.php.net/bug.php?id=67350&edit=1


Thread (12 messages)

« previous php.bugs (#186061) next »