diff options
author | Christian Stocker <chregu@php.net> | 2011-07-11 11:16:22 +0000 |
---|---|---|
committer | Christian Stocker <chregu@php.net> | 2011-07-11 11:16:22 +0000 |
commit | 0511fa337eac340af49432c56e2c1d19f1d680d9 (patch) | |
tree | 4fc1aae888cd6d144145ce34052cb0fd92102958 | |
parent | 0f3e70fe014dd4d40773f01c35b4b6451c76e300 (diff) | |
download | php-git-0511fa337eac340af49432c56e2c1d19f1d680d9.tar.gz |
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
-rw-r--r-- | NEWS | 5 | ||||
-rwxr-xr-x | UPGRADING | 3 | ||||
-rw-r--r-- | ext/xsl/php_xsl.c | 8 | ||||
-rw-r--r-- | ext/xsl/php_xsl.h | 9 | ||||
-rw-r--r-- | ext/xsl/xsl_fe.h | 3 | ||||
-rw-r--r-- | ext/xsl/xsltprocessor.c | 82 |
6 files changed, 110 insertions, 0 deletions
@@ -203,6 +203,11 @@ PHP NEWS . Added SplObjectStorage::getHash() hook. (Etienne) . Added CallbackFilterIterator and RecursiveCallbackFilterIterator (Arnaud) +- Improved XSL extension: + . 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 + - Improved ZLIB extension: . Re-implemented non-file related functionality. (Mike) @@ -174,6 +174,9 @@ UPGRADE NOTES - PHP X.Y just the first matching node. - All SimpleXMLElement children are now always printed when using var_dump(), var_export(), and print_r(). +- Write operations within XSLT (for example with the extension sax:output) are + disabled by default. You can define what is forbidden with the method + XsltProcess::setSecurityPrefs($options) =================================== 5. Changes made to existing methods diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c index 90f45be280..13ed910b5d 100644 --- a/ext/xsl/php_xsl.c +++ b/ext/xsl/php_xsl.c @@ -126,6 +126,7 @@ 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; zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); @@ -166,6 +167,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); diff --git a/ext/xsl/php_xsl.h b/ext/xsl/php_xsl.h index 5d1ffa5c3f..8782077413 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 <libxslt/xsltInternals.h> #include <libxslt/xsltutils.h> #include <libxslt/transform.h> +#include <libxslt/security.h> #if HAVE_XSL_EXSLT #include <libexslt/exslt.h> #include <libexslt/exsltconfig.h> @@ -43,6 +44,13 @@ extern zend_module_entry xsl_module_entry; #include <libxslt/extensions.h> #include <libxml/xpathInternals.h> +#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; @@ -55,6 +63,7 @@ typedef struct _xsl_object { HashTable *node_list; php_libxml_node_object *doc; char *profiling; + long securityPrefs; } xsl_object; void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC); diff --git a/ext/xsl/xsl_fe.h b/ext/xsl/xsl_fe.h index f6bc1f5ae0..a9fb16b2b2 100644 --- a/ext/xsl/xsl_fe.h +++ b/ext/xsl/xsl_fe.h @@ -34,6 +34,9 @@ PHP_FUNCTION(xsl_xsltprocessor_remove_parameter); PHP_FUNCTION(xsl_xsltprocessor_has_exslt_support); PHP_FUNCTION(xsl_xsltprocessor_register_php_functions); PHP_FUNCTION(xsl_xsltprocessor_set_profiling); +PHP_FUNCTION(xsl_xsltprocessor_set_security_prefs); +PHP_FUNCTION(xsl_xsltprocessor_get_security_prefs); + #endif /* diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index 8cb3415167..4d27b9cbf1 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -71,6 +71,13 @@ ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_set_profiling, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_set_security_prefs, 0, 0, 1) + ZEND_ARG_INFO(0, securityPrefs) +ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_get_security_prefs, 0, 0, 0) +ZEND_END_ARG_INFO(); /* }}} */ /* @@ -91,6 +98,8 @@ const zend_function_entry php_xsl_xsltprocessor_class_functions[] = { PHP_FALIAS(hasExsltSupport, xsl_xsltprocessor_has_exslt_support, arginfo_xsl_xsltprocessor_has_exslt_support) PHP_FALIAS(registerPHPFunctions, xsl_xsltprocessor_register_php_functions, arginfo_xsl_xsltprocessor_register_php_functions) PHP_FALIAS(setProfiling, xsl_xsltprocessor_set_profiling, arginfo_xsl_xsltprocessor_set_profiling) + PHP_FALIAS(setSecurityPrefs, xsl_xsltprocessor_set_security_prefs, arginfo_xsl_xsltprocessor_set_security_prefs) + PHP_FALIAS(getSecurityPrefs, xsl_xsltprocessor_get_security_prefs, arginfo_xsl_xsltprocessor_get_security_prefs) {NULL, NULL, NULL} }; @@ -531,11 +540,46 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl } efree(member); + /* Add security checks */ + /* XSLT_SECPREF_READ_FILE and XSLT_SECPREF_READ_NETWORK aren't needed */ + + xsltSecurityPrefsPtr secPrefs = xsltNewSecurityPrefs(); + + if (intern->securityPrefs & XSL_SECPREF_READ_FILE ) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't set libxslt security properties"); + } + } + if (intern->securityPrefs & XSL_SECPREF_WRITE_FILE ) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't set libxslt security properties"); + } + } + if (intern->securityPrefs & XSL_SECPREF_CREATE_DIRECTORY ) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't set libxslt security properties"); + } + } + if (intern->securityPrefs & XSL_SECPREF_READ_NETWORK) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't set libxslt security properties"); + } + } + if (intern->securityPrefs & XSL_SECPREF_WRITE_NETWORK) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't set libxslt security properties"); + } + } + + if (0 != xsltSetCtxtSecurityPrefs(secPrefs, ctxt)) + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't set libxslt security handler"); + newdocp = xsltApplyStylesheetUser(style, doc, (const char**) params, NULL, f, ctxt); if (f) { fclose(f); } xsltFreeTransformContext(ctxt); + xsltFreeSecurityPrefs(secPrefs); if (intern->node_list != NULL) { zend_hash_destroy(intern->node_list); @@ -857,6 +901,44 @@ PHP_FUNCTION(xsl_xsltprocessor_set_profiling) } /* }}} end xsl_xsltprocessor_set_profiling */ +/* {{{ proto long xsl_xsltprocessor_set_security_prefs(long securityPrefs) */ +PHP_FUNCTION(xsl_xsltprocessor_set_security_prefs) +{ + zval *id; + xsl_object *intern; + DOM_GET_THIS(id); + long securityPrefs, oldSecurityPrefs; + + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "l", &securityPrefs) == SUCCESS) { + intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); + oldSecurityPrefs = intern->securityPrefs; + intern->securityPrefs = securityPrefs; + RETURN_LONG(oldSecurityPrefs); + } else { + WRONG_PARAM_COUNT; + } +} +/* }}} end xsl_xsltprocessor_set_security_prefs */ + +/* {{{ proto long xsl_xsltprocessor_get_security_prefs() */ +PHP_FUNCTION(xsl_xsltprocessor_get_security_prefs) +{ + zval *id; + xsl_object *intern; + DOM_GET_THIS(id); + long securityPrefs; + + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "") == SUCCESS) { + intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); + RETURN_LONG(intern->securityPrefs); + } else { + WRONG_PARAM_COUNT; + } +} +/* }}} end xsl_xsltprocessor_get_security_prefs */ + + + /* {{{ proto bool xsl_xsltprocessor_has_exslt_support(); */ PHP_FUNCTION(xsl_xsltprocessor_has_exslt_support) |