diff options
author | Christian Stocker <chregu@php.net> | 2011-10-10 07:59:19 +0000 |
---|---|---|
committer | Christian Stocker <chregu@php.net> | 2011-10-10 07:59:19 +0000 |
commit | eb039d57839a81f43ae010877c9d91053de025f1 (patch) | |
tree | a8d359270fbbce9d458700b49a23c0c29e2de0d1 | |
parent | da110e2065d9a45756194051a9f02637e5d6fbf7 (diff) | |
download | php-git-eb039d57839a81f43ae010877c9d91053de025f1.tar.gz |
Added the xsl.security_prefs option to 5_4 and trunk and
mark it as deprecated for BC-reasons
Added tests for ini option and combination of both
-rw-r--r-- | ext/xsl/php_xsl.c | 17 | ||||
-rw-r--r-- | ext/xsl/php_xsl.h | 3 | ||||
-rw-r--r-- | ext/xsl/tests/bug54446_with_ini.phpt | 135 | ||||
-rw-r--r-- | ext/xsl/xsltprocessor.c | 35 |
4 files changed, 181 insertions, 9 deletions
diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c index f8d2519def..8160fec64d 100644 --- a/ext/xsl/php_xsl.c +++ b/ext/xsl/php_xsl.c @@ -126,7 +126,8 @@ zend_object_value xsl_objects_new(zend_class_entry *class_type TSRMLS_DC) intern->node_list = NULL; intern->doc = NULL; intern->profiling = NULL; - intern->securityPrefs = XSL_SECPREF_WRITE_FILE | XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_CREATE_DIRECTORY; + intern->securityPrefs = XSL_SECPREF_DEFAULT; + intern->securityPrefsSet = 0; zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); @@ -141,6 +142,13 @@ zend_object_value xsl_objects_new(zend_class_entry *class_type TSRMLS_DC) } /* }}} */ +PHP_INI_BEGIN() +/* Default is not allowing any write operations. + XSL_SECPREF_CREATE_DIRECTORY | XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_WRITE_FILE == 44 +*/ +PHP_INI_ENTRY("xsl.security_prefs", "44", PHP_INI_ALL, NULL) +PHP_INI_END() + /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(xsl) @@ -173,7 +181,8 @@ PHP_MINIT_FUNCTION(xsl) REGISTER_LONG_CONSTANT("XSL_SECPREF_CREATE_DIRECTORY", XSL_SECPREF_CREATE_DIRECTORY, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("XSL_SECPREF_READ_NETWORK", XSL_SECPREF_READ_NETWORK, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("XSL_SECPREF_WRITE_NETWORK", XSL_SECPREF_WRITE_NETWORK, CONST_CS | CONST_PERSISTENT); - + REGISTER_LONG_CONSTANT("XSL_SECPREF_DEFAULT", XSL_SECPREF_DEFAULT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("LIBXSLT_VERSION", LIBXSLT_VERSION, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("LIBXSLT_DOTTED_VERSION", LIBXSLT_DOTTED_VERSION, CONST_CS | CONST_PERSISTENT); @@ -182,6 +191,8 @@ PHP_MINIT_FUNCTION(xsl) REGISTER_STRING_CONSTANT("LIBEXSLT_DOTTED_VERSION", LIBEXSLT_DOTTED_VERSION, CONST_CS | CONST_PERSISTENT); #endif + REGISTER_INI_ENTRIES(); + return SUCCESS; } /* }}} */ @@ -265,6 +276,8 @@ PHP_MSHUTDOWN_FUNCTION(xsl) xsltCleanupGlobals(); + UNREGISTER_INI_ENTRIES(); + return SUCCESS; } /* }}} */ diff --git a/ext/xsl/php_xsl.h b/ext/xsl/php_xsl.h index 8782077413..40f5361a12 100644 --- a/ext/xsl/php_xsl.h +++ b/ext/xsl/php_xsl.h @@ -50,6 +50,8 @@ extern zend_module_entry xsl_module_entry; #define XSL_SECPREF_CREATE_DIRECTORY 8 #define XSL_SECPREF_READ_NETWORK 16 #define XSL_SECPREF_WRITE_NETWORK 32 +/* Default == disable all write access == XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_CREATE_DIRECTORY | XSL_SECPREF_WRITE_FILE */ +#define XSL_SECPREF_DEFAULT 44 typedef struct _xsl_object { zend_object std; @@ -64,6 +66,7 @@ typedef struct _xsl_object { php_libxml_node_object *doc; char *profiling; long securityPrefs; + int securityPrefsSet; } xsl_object; void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC); diff --git a/ext/xsl/tests/bug54446_with_ini.phpt b/ext/xsl/tests/bug54446_with_ini.phpt new file mode 100644 index 0000000000..fbe03659d3 --- /dev/null +++ b/ext/xsl/tests/bug54446_with_ini.phpt @@ -0,0 +1,135 @@ +--TEST-- +Bug #54446 (Arbitrary file creation via libxslt 'output' extension with php.ini setting) +--SKIPIF-- +<?php +if (!extension_loaded('xsl')) die("skip Extension XSL is required\n"); +?> +--FILE-- +<?php +include("prepare.inc"); + +$outputfile = dirname(__FILE__)."/bug54446test.txt"; +if (file_exists($outputfile)) { + unlink($outputfile); +} + +$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="/"> + <sax:output href="$outputfile" method="text"> + <xsl:value-of select="'0wn3d via PHP and libxslt ...'"/> + </sax:output> + </xsl:template> + +</xsl:stylesheet> +EOT; + +$xsl->loadXML( $sXsl ); + +# START XSLT +$proc->importStylesheet( $xsl ); + +# TRASNFORM & PRINT +print $proc->transformToXML( $dom ); + + +if (file_exists($outputfile)) { + print "$outputfile exists, but shouldn't!\n"; +} else { + print "OK, no file created\n"; +} + +#SET NO SECURITY PREFS +ini_set("xsl.security_prefs", XSL_SECPREF_NONE); + +# TRASNFORM & PRINT +print $proc->transformToXML( $dom ); + + +if (file_exists($outputfile)) { + print "OK, file exists\n"; +} else { + print "$outputfile doesn't exist, but should!\n"; +} + +unlink($outputfile); + +#SET SECURITY PREFS AGAIN +ini_set("xsl.security_prefs", XSL_SECPREF_WRITE_FILE | XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_CREATE_DIRECTORY); + +# TRASNFORM & PRINT +print $proc->transformToXML( $dom ); + +if (file_exists($outputfile)) { + print "$outputfile exists, but shouldn't!\n"; +} else { + print "OK, no file created\n"; +} + +#SET NO SECURITY PREFS with ini, but set them with ->setSecurityPrefs +ini_set("xsl.security_prefs", XSL_SECPREF_NONE); +$proc->setSecurityPrefs( XSL_SECPREF_WRITE_FILE | XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_CREATE_DIRECTORY); + +print $proc->transformToXML( $dom ); +if (file_exists($outputfile)) { + print "$outputfile exists, but shouldn't!\n"; +} else { + print "OK, no file created\n"; +} + +#don't throw a warning if both ini and through-the-method have the same value +$proc->setSecurityPrefs(XSL_SECPREF_NONE); + +print $proc->transformToXML( $dom ); + +if (file_exists($outputfile)) { + print "OK, file exists\n"; +} else { + print "$outputfile doesn't exist, but should!\n"; +} +unlink($outputfile); + + + +--EXPECTF-- +Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %s element output in %s on line %d + +Warning: XSLTProcessor::transformToXml(): File write for %s/bug54446test.txt refused in %s on line %s + +Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %d element output in %s on line %d + +Warning: XSLTProcessor::transformToXml(): xsltDocumentElem: write rights for %s/bug54446test.txt denied in %s on line %d +OK, no file created + +Deprecated: XSLTProcessor::transformToXml(): The xsl.security_prefs php.ini option is deprecated; use XsltProcessor->setSecurityPrefs() instead in %s on line %d +OK, file exists + +Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %s element output in %s on line %d + +Warning: XSLTProcessor::transformToXml(): File write for %s/bug54446test.txt refused in %s on line %s + +Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %d element output in %s on line %d + +Warning: XSLTProcessor::transformToXml(): xsltDocumentElem: write rights for %s/bug54446test.txt denied in %s on line %d +OK, no file created + +Deprecated: XSLTProcessor::transformToXml(): The xsl.security_prefs php.ini option is deprecated; use XsltProcessor->setSecurityPrefs() instead in %s on line %d + +Notice: XSLTProcessor::transformToXml(): The xsl.security_prefs php.ini was not used, since the XsltProcessor->setSecurityPrefs() method was used in %s on line %d + +Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %s element output in %s on line %d + +Warning: XSLTProcessor::transformToXml(): File write for %s/bug54446test.txt refused in %s on line %s + +Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %d element output in %s on line %d + +Warning: XSLTProcessor::transformToXml(): xsltDocumentElem: write rights for %s/bug54446test.txt denied in %s on line %d +OK, no file created +OK, file exists +--CREDITS-- +Christian Stocker, chregu@php.net + diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index 32197c8158..c62403fb8c 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -487,6 +487,7 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl zend_object_handlers *std_hnd; FILE *f; int secPrefsError = 0; + int secPrefsValue, secPrefsIni; xsltSecurityPrefsPtr secPrefs = NULL; node = php_libxml_import_node(docp TSRMLS_CC); @@ -544,31 +545,49 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl } efree(member); + secPrefsValue = intern->securityPrefs; - //if securityPrefs is set to NONE, we don't have to do any checks, but otherwise... - if (intern->securityPrefs != XSL_SECPREF_NONE) { + /* This whole if block can be removed, when we remove the xsl.security_prefs php.ini option in PHP 6+ */ + secPrefsIni= INI_INT("xsl.security_prefs"); + /* if secPrefsIni has the same value as secPrefsValue, all is fine */ + if (secPrefsIni != secPrefsValue) { + if (secPrefsIni != XSL_SECPREF_DEFAULT) { + /* if the ini value is not set to the default, throw an E_DEPRECATED warning */ + php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The xsl.security_prefs php.ini option is deprecated; use XsltProcessor->setSecurityPrefs() instead"); + if (intern->securityPrefsSet == 0) { + /* if securityPrefs were not set through the setSecurityPrefs method, take the ini setting */ + secPrefsValue = secPrefsIni; + } else { + /* else throw a notice, that the ini setting was not used */ + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "The xsl.security_prefs php.ini was not used, since the XsltProcessor->setSecurityPrefs() method was used"); + } + } + } + + /* if securityPrefs is set to NONE, we don't have to do any checks, but otherwise... */ + if (secPrefsValue != XSL_SECPREF_NONE) { secPrefs = xsltNewSecurityPrefs(); - if (intern->securityPrefs & XSL_SECPREF_READ_FILE ) { + if (secPrefsValue & XSL_SECPREF_READ_FILE ) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid)) { secPrefsError = 1; } } - if (intern->securityPrefs & XSL_SECPREF_WRITE_FILE ) { + if (secPrefsValue & XSL_SECPREF_WRITE_FILE ) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid)) { secPrefsError = 1; } } - if (intern->securityPrefs & XSL_SECPREF_CREATE_DIRECTORY ) { + if (secPrefsValue & XSL_SECPREF_CREATE_DIRECTORY ) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid)) { secPrefsError = 1; } } - if (intern->securityPrefs & XSL_SECPREF_READ_NETWORK) { + if (secPrefsValue & XSL_SECPREF_READ_NETWORK) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid)) { secPrefsError = 1; } } - if (intern->securityPrefs & XSL_SECPREF_WRITE_NETWORK) { + if (secPrefsValue & XSL_SECPREF_WRITE_NETWORK) { if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid)) { secPrefsError = 1; } @@ -927,6 +946,8 @@ PHP_FUNCTION(xsl_xsltprocessor_set_security_prefs) intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); oldSecurityPrefs = intern->securityPrefs; intern->securityPrefs = securityPrefs; + /* set this to 1 so that we know, it was set through this method. Can be removed, when we remove the ini setting */ + intern->securityPrefsSet = 1; RETURN_LONG(oldSecurityPrefs); } /* }}} end xsl_xsltprocessor_set_security_prefs */ |