8000 [2.3] Fix libxml_use_internal_errors and libxml_disable_entity_loader usage by romainneutron · Pull Request #10493 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[2.3] Fix libxml_use_internal_errors and libxml_disable_entity_loader usage #10493

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

romainneutron
Copy link
Contributor
Q A
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #9731, #9483
License MIT

This should fix #9731 and #9483 that seems to be triggered when libxml_disable_entity_loader has been called with true (see https://bugs.php.net/bug.php?id=62577)
As libxml_disable_entity_loader is non thread safe (see https://bugs.php.net/bug.php?id=64938) and as we have some calls that might leave the setting to true, I think the bug should be fixed.

I've checked the use of both libxml_use_internal_errors and libxml_disable_entity_loader among symfony code.

You can see I prefered to skip DomDocument::loadXML warnings using the @ instead of using LIBXML_NOERROR | LIBXML_NO_WARNING because we can log these errors whereas libxml errors would be furtives.

  • Check calls to DOMDocument::load
  • Check calls to DOMDocument::loadXML
  • Check calls to DOMDocument::loadHTML
  • Check calls to DOMDocument::loadHTMLFile
  • Add more tests

@romainneutron
Copy link
Contributor Author

@Tobion
Copy link
Contributor
Tobion commented Mar 19, 2014

So it will still not load the xml or schema, but just surpress the error message, or?

@romainneutron
Copy link
Contributor Author

Hi @Tobion. No, it will load the XML. It's about restoring global XML settings after an error occured to avoid trigger https://bugs.php.net/bug.php?id=62577.

What I think is that DOMDocument::loadXML is called at https://github.com/symfony/symfony/blob/2.3/src/Symfony/Component/Config/Util/XmlUtils.php#L49 with a wrong XML, then a warning is emitted and thrown as an exception.
Since the next line is not called and libxml_disable_entity_loader is not thread safe, next call using libxml might trigger https://bugs.php.net/bug.php?id=62577. Issues described that only a restart of php-fpm solves the error.

@Tobion
Copy link
Contributor
Tobion commented Mar 19, 2014

I see. What about using try .. catch around $dom->load instead of using @?

@Tobion
Copy link
Contributor
Tobion commented Mar 19, 2014

I think QtFileLoader could use XmlUtils to reuse some code. Config Component is required for this class anyway.

@@ -59,6 +59,8 @@ public function testHtmlIds($css, array $elementsId)
$this->assertTrue(in_array($element->attributes()->id, $elementsId));
}
}
libxml_clear_errors();
libxml_use_internal_errors(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be set to the previous value like in other tests?

@romainneutron
Copy link
Contributor Author

I've reproduced the issue and added a test.
The bug is now identified, here are the step to reproduce:

A method call libxml_disable_entity_loader with true prior DOMDocument::load, DOMDocument::loadXML, DOMDocument::loadHTML or DOMDocument::loadHTMLFile . If an empty XML is passed, then a E_WARNING error is generated, thrown as an exception because of an error handler, and the previous value of libxml_disable_entity_loader is not restored.

I'm gonna check other calls and ensure that empty XML will be discard before an exception is thrown

@romainneutron romainneutron changed the title [2.3] Fix libxml_use_internal_errors and libxml_disable_entity_loader usage [WIP][2.3] Fix libxml_use_internal_errors and libxml_disable_entity_loader usage Mar 19, 2014
@romainneutron
Copy link
Contributor Author

Updating the issue to WIP, add tasks

@romainneutron romainneutron changed the title [WIP][2.3] Fix libxml_use_internal_errors and libxml_disable_entity_loader usage [2.3] Fix libxml_use_internal_errors and libxml_disable_entity_loader usage Mar 20, 2014
@romainneutron
Copy link
Contributor Author

PR updated, I've addressed comments.

@Tobion I've updated QtFileLoader as well as XliffFileLoader so they use XmlUtils. XmlUtils throws an exception if a document type is present in the XML whereas QtFileLoader did not. Should we throw an exception in case a XML containing a document type is passed to QtFileLoader ? In case we should not, I must revert changes

Outside of that check, I think things are done


try {
XmlUtils::loadFile(__DIR__.'/../Fixtures/foo.xml');
$this->fail('An exception should have been raised');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work because you are catching all exceptions, and so catching the failure

@Tobion
Copy link
Contributor
Tobion commented Mar 20, 2014

@romainneutron IMO QtFileLoader should also forbig doc types definitions. As far as I know, they have been disabled for the other loaders because of potential security issues. See http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html#xml-external-entity-injection
So it should be forbidden for all xml loaders.

$internalErrors = libxml_use_internal_errors(true);
$disableEntities = libxml_disable_entity_loader(true);
libxml_clear_errors();

$dom = new \DOMDocument();
$dom->validateOnParse = true;
if (!$dom->loadXML(file_get_contents($file), LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) {
if (!$dom->loadXML($content, LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you fixed the root cause with empty xml. but should it not still use either @ or try..catch in case there are other circumstances where an error is raised. the idea was that libxml_disable_entity_loader is reset to its previous state in any way, wasn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the ides was that libxml_disable_entity_loader must be reset in its previous state in any way.

We actually don't need to silently discard any error on DomDocument::loadXML : A warning is generated only if the passed content is equal to '' when cast to string. In any other case, no error/warning are generated because these errors are managed by libxml (we set libxml_use_internal_errors to true)

No exceptions / errors / warning could be thrown or generated

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@romainneutron
Copy link
Contributor Author

I've addressed comments, this PR is updated

@Tobion
Copy link
Contributor
Tobion commented Mar 20, 2014

+1

fabpot added a commit that referenced this pull request Mar 26, 2014
…tity_loader usage (romainneutron)

This PR was merged into the 2.3 branch.

Discussion
----------

[2.3] Fix libxml_use_internal_errors and libxml_disable_entity_loader usage

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #9731, #9483
| License       | MIT

This should fix #9731 and #9483 that seems to be triggered when `libxml_disable_entity_loader` has been called with `true` (see https://bugs.php.net/bug.php?id=62577)
As `libxml_disable_entity_loader` is non thread safe (see https://bugs.php.net/bug.php?id=64938) and as we have some calls that might leave the setting to `true`, I think the bug should be fixed.

I've checked the use of both `libxml_use_internal_errors` and `libxml_disable_entity_loader` among symfony code.

You can see I prefered to skip DomDocument::loadXML warnings using the `@` instead of using `LIBXML_NOERROR | LIBXML_NO_WARNING` because we can log these errors whereas libxml errors would be furtives.

 - [x] Check calls to DOMDocument::load
 - [x] Check calls to DOMDocument::loadXML
 - [x] Check calls to DOMDocument::loadHTML
 - [x] Check calls to DOMDocument::loadHTMLFile
 - [x] Add more tests

Commits
-------

489b8ae Fix libxml_use_internal_errors and libxml_disable_entity_loader usage
@fabpot fabpot closed this Mar 26, 2014
@maphe
Copy link
maphe commented Mar 26, 2014

Is it possible to merge into 2.4, please?

@jakzal
Copy link
Contributor
jakzal commented Mar 26, 2014

@maphe older branches are merged into newer ones regurarly, so it will be merged into 2.4 and master at some point.

@maphe
Copy link
maphe commented Mar 26, 2014

thanks @jakzal what's the period approximately?

@jakzal
Copy link
Contributor
jakzal commented Mar 26, 2014

few days. up to a week usually.

@maphe
Copy link
maphe commented Mar 26, 2014

OK perfect. Thank you

fabpot added a commit that referenced this pull request Jul 1, 2014
…sable_entity_loader usage (ccorliss)

This PR was submitted for the 2.4 branch but it was merged into the 2.3 branch instead (closes #11259).

Discussion
----------

[Config] Fixed failed config schema loads due to libxml_disable_entity_loader usage

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #11258
| License       | MIT
| Doc PR        | N/A

PR #10493 helped this issue, but it can still affect users that:

1.  Have libxml_disable_entity_loader set to true by default.
2.  Experience libxml_disable_entity_loader php bug https://bugs.php.net/bug.php?id=64938

I used the same approach used in the DI xml validation.
https://github.com/symfony/symfony/blob/master/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php#L452

Commits
-------

de2bef5 Fixed failed config schema loads due to libxml_disable_entity_loader usage.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants
0