Skip to content

Commit f0441e0

Browse files
authored
Add LIBXML_NO_XXE constant (php#14844)
This constant is available as of libxml2 2.13, and is used together with LIBXML_NOENT to allow entity subsitution but disallow external entities.
1 parent 1f64e7c commit f0441e0

File tree

8 files changed

+86
-5
lines changed

8 files changed

+86
-5
lines changed

NEWS

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.4.0alpha2
44

5-
- PDO
5+
- LibXML:
6+
. Added LIBXML_NO_XXE constant. (nielsdos)
7+
8+
- PDO:
69
. Fixed bug GH-14792 (Compilation failure on pdo_* extensions).
710
(Peter Kokot)
811

UPGRADING

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,10 @@ PHP 8.4 UPGRADE NOTES
763763

764764
- LibXML:
765765
. LIBXML_RECOVER.
766+
. LIBXML_NO_XXE.
767+
This is used together with LIBXML_NOENT for when you want to perform entity
768+
substitution, but want to disallow external entity loading.
769+
This constant is available as of libxml2 2.13.
766770

767771
- OpenSSL:
768772
. X509_PURPOSE_OCSP_HELPER.

ext/dom/tests/modern/xml/XMLDocument_fromString_03.phpt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,17 @@ $flags = [
1212
try {
1313
Dom\XMLDocument::createFromString('<?xml version="1.0"?><container/>', -1);
1414
} catch (ValueError $e) {
15-
echo $e->getMessage();
15+
echo $e->getMessage(), "\n";
1616
}
1717

1818
foreach ($flags as $flag) {
1919
var_dump(Dom\XMLDocument::createFromString('<?xml version="1.0"?><container/>', $flag) instanceof Dom\XMLDocument);
2020
}
2121

2222
?>
23-
--EXPECT--
24-
Dom\XMLDocument::createFromString(): Argument #2 ($options) contains invalid flags (allowed flags: LIBXML_RECOVER, LIBXML_NOENT, LIBXML_DTDLOAD, LIBXML_DTDATTR, LIBXML_DTDVALID, LIBXML_NOERROR, LIBXML_NOWARNING, LIBXML_NOBLANKS, LIBXML_XINCLUDE, LIBXML_NSCLEAN, LIBXML_NOCDATA, LIBXML_NONET, LIBXML_PEDANTIC, LIBXML_COMPACT, LIBXML_PARSEHUGE, LIBXML_BIGLINES)bool(true)
23+
--EXPECTF--
24+
Dom\XMLDocument::createFromString(): Argument #2 ($options) contains invalid flags (allowed flags: %s)
25+
bool(true)
2526
bool(true)
2627
bool(true)
2728
bool(true)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Test flag LIBXML_NO_XXE
3+
--EXTENSIONS--
4+
dom
5+
--SKIPIF--
6+
<?php
7+
if (!defined('LIBXML_NO_XXE')) die('skip LIBXML_NO_XXE not available');
8+
?>
9+
--FILE--
10+
<?php
11+
$xml = <<< XML
12+
<?xml version='1.0' encoding='utf-8'?>
13+
<!DOCTYPE set [
14+
<!ENTITY foo '<foo>bar</foo>'>
15+
<!ENTITY xxe SYSTEM "file:///etc/passwd">
16+
]>
17+
<set>&foo;&xxe;</set>
18+
XML;
19+
20+
$doc = Dom\XMLDocument::createFromString($xml, LIBXML_NOENT | LIBXML_NO_XXE);
21+
echo $doc->saveXML();
22+
?>
23+
--EXPECT--
24+
<?xml version="1.0" encoding="utf-8"?>
25+
<!DOCTYPE set [
26+
<!ENTITY foo "<foo>bar</foo>">
27+
<!ENTITY xxe SYSTEM "file:///etc/passwd">
28+
]>
29+
<set><foo>bar</foo></set>

ext/dom/xml_document.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ static bool check_options_validity(uint32_t arg_num, zend_long options)
2929
{
3030
const zend_long VALID_OPTIONS = XML_PARSE_RECOVER
3131
| XML_PARSE_NOENT
32+
#if LIBXML_VERSION >= 21300
33+
| XML_PARSE_NO_XXE
34+
#endif
3235
| XML_PARSE_DTDLOAD
3336
| XML_PARSE_DTDATTR
3437
| XML_PARSE_DTDVALID
@@ -47,6 +50,9 @@ static bool check_options_validity(uint32_t arg_num, zend_long options)
4750
zend_argument_value_error(arg_num, "contains invalid flags (allowed flags: "
4851
"LIBXML_RECOVER, "
4952
"LIBXML_NOENT, "
53+
#if LIBXML_VERSION >= 21300
54+
"LIBXML_NO_XXE, "
55+
#endif
5056
"LIBXML_DTDLOAD, "
5157
"LIBXML_DTDATTR, "
5258
"LIBXML_DTDVALID, "

ext/libxml/libxml.stub.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@
2828
* @cvalue XML_PARSE_NOENT
2929
*/
3030
const LIBXML_NOENT = UNKNOWN;
31+
#if LIBXML_VERSION >= 21300
32+
/**
33+
* @var int
34+
* @cvalue XML_PARSE_NO_XXE
35+
*/
36+
const LIBXML_NO_XXE = UNKNOWN;
37+
#endif
3138
/**
3239
* @var int
3340
* @cvalue XML_PARSE_DTDLOAD

ext/libxml/libxml_arginfo.h

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
XML parsing with LIBXML_NO_XXE
3+
--EXTENSIONS--
4+
simplexml
5+
--SKIPIF--
6+
<?php
7+
if (!defined('LIBXML_NO_XXE')) die('skip LIBXML_NO_XXE not available');
8+
?>
9+
--FILE--
10+
<?php
11+
12+
$xml = <<< XML
13+
<?xml version='1.0' encoding='utf-8'?>
14+
<!DOCTYPE set [
15+
<!ENTITY foo '<foo>bar</foo>'>
16+
<!ENTITY xxe SYSTEM "file:///etc/passwd">
17+
]>
18+
<set>&foo;&xxe;</set>
19+
XML;
20+
21+
var_dump(simplexml_load_string($xml, options: LIBXML_NOENT | LIBXML_NO_XXE));
22+
23+
?>
24+
--EXPECT--
25+
object(SimpleXMLElement)#1 (1) {
26+
["foo"]=>
27+
string(3) "bar"
28+
}

0 commit comments

Comments
 (0)