From: Christian Stocker Date: Wed, 5 Oct 2011 09:56:01 +0000 (+0000) Subject: Added xsl.security_prefs ini option to define forbidden operations within XSLT X-Git-Tag: php-5.3.9RC1~68 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b2287a42a0dfd8fe392051d8f25531051cd86322;p=php 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 --- diff --git a/NEWS b/NEWS index b68cb0136c..680929a6d8 100644 --- a/NEWS +++ b/NEWS @@ -90,6 +90,12 @@ PHP NEWS - SPL: . Fixed bug #55807 (Wrong value for splFileObject::SKIP_EMPTY). (jgotti at modedemploi dot fr, Hannes) + +- XSL: + . 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 (Chregu, Nicolas Gregoire) + 23 Aug 2011, PHP 5.3.8 diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c index 8c34b1e986..6e70c40ec3 100644 --- a/ext/xsl/php_xsl.c +++ b/ext/xsl/php_xsl.c @@ -141,6 +141,11 @@ zend_object_value xsl_objects_new(zend_class_entry *class_type TSRMLS_DC) } /* }}} */ +PHP_INI_BEGIN() +//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) @@ -167,6 +172,13 @@ PHP_MINIT_FUNCTION(xsl) REGISTER_LONG_CONSTANT("XSL_CLONE_NEVER", -1, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("XSL_CLONE_ALWAYS", 1, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XSL_SECPREF_NONE", XSL_SECPREF_NONE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XSL_SECPREF_READ_FILE", XSL_SECPREF_READ_FILE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("XSL_SECPREF_WRITE_FILE", XSL_SECPREF_WRITE_FILE, CONST_CS | CONST_PERSISTENT); + 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("LIBXSLT_VERSION", LIBXSLT_VERSION, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("LIBXSLT_DOTTED_VERSION", LIBXSLT_DOTTED_VERSION, CONST_CS | CONST_PERSISTENT); @@ -175,6 +187,8 @@ PHP_MINIT_FUNCTION(xsl) REGISTER_STRING_CONSTANT("LIBEXSLT_DOTTED_VERSION", LIBEXSLT_DOTTED_VERSION, CONST_CS | CONST_PERSISTENT); #endif + REGISTER_INI_ENTRIES(); + return SUCCESS; } /* }}} */ @@ -258,6 +272,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 5d1ffa5c3f..cf724fea18 100644 --- a/ext/xsl/php_xsl.h +++ b/ext/xsl/php_xsl.h @@ -32,6 +32,7 @@ extern zend_module_entry xsl_module_entry; #include #include #include +#include #if HAVE_XSL_EXSLT #include #include @@ -43,6 +44,13 @@ extern zend_module_entry xsl_module_entry; #include #include +#define XSL_SECPREF_NONE 0 +#define XSL_SECPREF_READ_FILE 2 +#define XSL_SECPREF_WRITE_FILE 4 +#define XSL_SECPREF_CREATE_DIRECTORY 8 +#define XSL_SECPREF_READ_NETWORK 16 +#define XSL_SECPREF_WRITE_NETWORK 32 + typedef struct _xsl_object { zend_object std; void *ptr; diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index e89b2ccca6..980ff5616c 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -475,6 +475,9 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl zval *doXInclude, *member; zend_object_handlers *std_hnd; FILE *f; + int secPrefsError; + int secPrefsIni; + xsltSecurityPrefsPtr secPrefs = NULL; node = php_libxml_import_node(docp TSRMLS_CC); @@ -531,11 +534,56 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl } efree(member); - newdocp = xsltApplyStylesheetUser(style, doc, (const char**) params, NULL, f, ctxt); + + secPrefsIni = INI_INT("xsl.security_prefs"); + + //if securityPrefs is set to NONE, we don't have to do any checks, but otherwise... + if (secPrefsIni != XSL_SECPREF_NONE) { + secPrefs = xsltNewSecurityPrefs(); + if (secPrefsIni & XSL_SECPREF_READ_FILE ) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid)) { + secPrefsError = 1; + } + } + if (secPrefsIni & XSL_SECPREF_WRITE_FILE ) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid)) { + secPrefsError = 1; + } + } + if (secPrefsIni & XSL_SECPREF_CREATE_DIRECTORY ) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid)) { + secPrefsError = 1; + } + } + if (secPrefsIni & XSL_SECPREF_READ_NETWORK) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid)) { + secPrefsError = 1; + } + } + if (secPrefsIni & XSL_SECPREF_WRITE_NETWORK) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid)) { + secPrefsError = 1; + } + } + + if (0 != xsltSetCtxtSecurityPrefs(secPrefs, ctxt)) { + secPrefsError = 1; + } + } + + if (secPrefsError == 1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't set libxslt security properties, not doing transformation for security reasons"); + } else { + newdocp = xsltApplyStylesheetUser(style, doc, (const char**) params, NULL, f, ctxt); + } if (f) { fclose(f); } + xsltFreeTransformContext(ctxt); + if (secPrefs) { + xsltFreeSecurityPrefs(secPrefs); + } if (intern->node_list != NULL) { zend_hash_destroy(intern->node_list);