]> granicus.if.org Git - php/commitdiff
Added the xsl.security_prefs option to 5_4 and trunk and
authorChristian Stocker <chregu@php.net>
Mon, 10 Oct 2011 07:59:19 +0000 (07:59 +0000)
committerChristian Stocker <chregu@php.net>
Mon, 10 Oct 2011 07:59:19 +0000 (07:59 +0000)
mark it as deprecated for BC-reasons
Added tests for ini option and combination of both

ext/xsl/php_xsl.c
ext/xsl/php_xsl.h
ext/xsl/tests/bug54446_with_ini.phpt [new file with mode: 0644]
ext/xsl/xsltprocessor.c

index f8d2519defad11a6ce624e13e3e8a8ee3433048e..b0078d82f53cbd9712712c4b18f5bbdb427214ac 100644 (file)
@@ -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,6 +181,7 @@ 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;
 }
 /* }}} */
index 8782077413a36a1ef631fab618dc4d0cb87441d6..40f5361a1279956c3c5503342c01be89bd4d4188 100644 (file)
@@ -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 (file)
index 0000000..fbe0365
--- /dev/null
@@ -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
+
index 32197c81583a99442dae7371cb29a393fbf20547..c62403fb8cd83467544678b5cc8481df1295a8a9 100644 (file)
@@ -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 */