]> granicus.if.org Git - php/commitdiff
Add the complement to the putenv() security
authorZeev Suraski <zeev@php.net>
Mon, 31 Jan 2000 22:31:00 +0000 (22:31 +0000)
committerZeev Suraski <zeev@php.net>
Mon, 31 Jan 2000 22:31:00 +0000 (22:31 +0000)
NEWS
ext/standard/basic_functions.c
ext/standard/basic_functions.h
php.ini-dist

diff --git a/NEWS b/NEWS
index b4c658571adf5901f57c756ec5c42c7f05086e65..4ced8b6cc5b2217fb65aa408a883966c7b34e7ab 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,8 +2,8 @@ PHP 4.0                                                                    NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 
 ?? ?? ????, Version 4.0 Beta 4
-- Added the ability to prevent the user from overriding certain environment
-  variables in Safe Mode (Zeev)
+- Added the ability to control the environment variables the user is allowed
+  to change in Safe Mode, using INI directives (Zeev)
 - Fixed a crash bug in strtr() working on large input strings (Zeev)
 - Ora_GetColumn()/Ora_FetchInto() now return NULL for NULL-Columns. (Thies)
 - OCI8 now supports binding of NULL-values. Module cleanups. (Thies)
index 8634288932a2523885c12f354ec72fbdab1b9935..f7c0a1745cc98e99a2bc5d0eec769eb415ce5c56 100644 (file)
@@ -314,11 +314,11 @@ static PHP_INI_MH(OnUpdateSafeModeProtectedEnvVars)
        BLS_FETCH();
 
        protected_vars = estrndup(new_value, new_value_length);
-       zend_hash_clean(&BG(protected_env_vars));
+       zend_hash_clean(&BG(sm_protected_env_vars));
 
        protected_var=strtok(protected_vars, ", ");
        while (protected_var) {
-               zend_hash_update(&BG(protected_env_vars), protected_var, strlen(protected_var), &dummy, sizeof(int), NULL);
+               zend_hash_update(&BG(sm_protected_env_vars), protected_var, strlen(protected_var), &dummy, sizeof(int), NULL);
                protected_var=strtok(NULL, ", ");
        }
        efree(protected_vars);
@@ -326,8 +326,21 @@ static PHP_INI_MH(OnUpdateSafeModeProtectedEnvVars)
 }
 
 
+static PHP_INI_MH(OnUpdateSafeModeAllowedEnvVars)
+{
+       BLS_FETCH();
+
+       if (BG(sm_allowed_env_vars)) {
+               free(BG(sm_allowed_env_vars));
+       }
+       BG(sm_allowed_env_vars) = zend_strndup(new_value, new_value_length);
+       return SUCCESS;
+}
+
+
 PHP_INI_BEGIN()
-       PHP_INI_ENTRY_EX("safe_mode_protected_env_vars",        SAFE_MODE_PROTECTED_ENV_VARS,   PHP_INI_SYSTEM,         OnUpdateSafeModeProtectedEnvVars,               NULL)
+       PHP_INI_ENTRY_EX("safe_mode_sm_protected_env_vars",     SAFE_MODE_PROTECTED_ENV_VARS,   PHP_INI_SYSTEM,         OnUpdateSafeModeProtectedEnvVars,               NULL)
+       PHP_INI_ENTRY_EX("safe_mode_allowed_env_vars",          SAFE_MODE_ALLOWED_ENV_VARS,             PHP_INI_SYSTEM,         OnUpdateSafeModeAllowedEnvVars,                 NULL)
 PHP_INI_END()
 
 
@@ -377,12 +390,16 @@ static void basic_globals_ctor(BLS_D)
 {
        BG(next) = NULL;
        BG(left) = -1;
-       zend_hash_init(&BG(protected_env_vars), 5, NULL, NULL, 1);
+       zend_hash_init(&BG(sm_protected_env_vars), 5, NULL, NULL, 1);
+       BG(sm_allowed_env_vars) = NULL;
 }
 
 static void basic_globals_dtor(BLS_D)
 {
-       zend_hash_destroy(&BG(protected_env_vars));
+       zend_hash_destroy(&BG(sm_protected_env_vars));
+       if (BG(sm_allowed_env_vars)) {
+               free(BG(sm_allowed_env_vars));
+       }
 }
 
 
@@ -536,7 +553,7 @@ PHP_FUNCTION(putenv)
                PLS_FETCH();
                
                if (PG(safe_mode)) {
-                       /* check the protected_env_vars table */
+                       /* check the sm_protected_env_vars table */
                }
 
                pe.putenv_string = estrndup((*str)->value.str.val,(*str)->value.str.len);
@@ -547,12 +564,36 @@ PHP_FUNCTION(putenv)
                pe.key_len = strlen(pe.key);
                pe.key = estrndup(pe.key,pe.key_len);
                
-               if (PG(safe_mode)
-                       && zend_hash_exists(&BG(protected_env_vars), pe.key, pe.key_len)) {
-                       php_error(E_WARNING, "Safe Mode:  Cannot override protected environment variable '%s'", pe.key);
-                       efree(pe.putenv_string);
-                       efree(pe.key);
-                       RETURN_FALSE;
+               if (PG(safe_mode)) {
+                       /* Check the protected list */
+                       if (zend_hash_exists(&BG(sm_protected_env_vars), pe.key, pe.key_len)) {
+                               php_error(E_WARNING, "Safe Mode:  Cannot override protected environment variable '%s'", pe.key);
+                               efree(pe.putenv_string);
+                               efree(pe.key);
+                               RETURN_FALSE;
+                       }
+
+                       /* Check the allowed list */
+                       if (BG(sm_allowed_env_vars) && *BG(sm_allowed_env_vars)) {
+                               char *allowed_env_vars = estrdup(BG(sm_allowed_env_vars));
+                               char *allowed_prefix = strtok(allowed_env_vars, ", ");
+                               zend_bool allowed=0;
+
+                               while (allowed_prefix) {
+                                       if (!strncmp(allowed_prefix, pe.key, strlen(allowed_prefix))) {
+                                               allowed=1;
+                                               break;
+                                       }
+                                       allowed_prefix = strtok(NULL, ", ");
+                               }
+                               efree(allowed_env_vars);
+                               if (!allowed) {
+                                       php_error(E_WARNING, "Safe Mode:  Cannot set environment variable '%s' - it's not in the allowed list", pe.key);
+                                       efree(pe.putenv_string);
+                                       efree(pe.key);
+                                       RETURN_FALSE;
+                               }
+                       }
                }
 
                zend_hash_del(&BG(putenv_ht),pe.key,pe.key_len+1);
index a47f522bec0ea20a9a818e0cb382cbbb4de24bed..62468cbba408f5ccd02c49a81c82304781896800 100644 (file)
@@ -136,7 +136,8 @@ typedef struct {
        zval **array_walk_func_name;
        zval **user_compare_func_name;
        
-       HashTable protected_env_vars;
+       HashTable sm_protected_env_vars;
+       char *sm_allowed_env_vars;
 
        /* pageinfo.c */
        long page_uid;
@@ -184,6 +185,7 @@ typedef struct {
 
 /* Values are comma-delimited
  */
-#define SAFE_MODE_PROTECTED_ENV_VARS "LD_LIBRARY_PATH"
+#define SAFE_MODE_PROTECTED_ENV_VARS   "LD_LIBRARY_PATH"
+#define SAFE_MODE_ALLOWED_ENV_VARS             "PHP_"
 
 #endif /* _BASIC_FUNCTIONS_H */
index 844bf100e878e29d632c9a5177507ff2776cabb9..38d81de95b59a682c72b7f1051b8a2295ac9ebd3 100644 (file)
@@ -77,12 +77,26 @@ allow_call_time_pass_reference      = On    ; whether to enable the ability to force arg
 ; Safe Mode
 safe_mode              =       Off
 safe_mode_exec_dir     =
-safe_mode_protected_env_vars = LD_LIBRARY_PATH         ; In Safe Mode, setting certain environment
-                                                                                                       ; variables may be a potential security
-                                                                                                       ; breach.  This directive contains
-                                                                                                       ; a comma delimited list of environment
-                                                                                                       ; variables, that the end user won't be
-                                                                                                       ; able to override using putenv()
+safe_mode_allowed_env_vars = PHP_                                      ; Setting certain environment variables
+                                                                                                       ; may be a potential security breach.
+                                                                                                       ; This directive contains a comma-delimited
+                                                                                                       ; list of prefixes.  In Safe Mode, the
+                                                                                                       ; user may only alter environment
+                                                                                                       ; variables whose names begin with the
+                                                                                                       ; prefixes supplied here.
+                                                                                                       ; By default, users will only be able
+                                                                                                       ; to set environment variables that begin
+                                                                                                       ; with PHP_ (e.g. PHP_FOO=BAR).
+                                                                                                       ; Note:  If this directive is empty, PHP
+                                                                                                       ; will let the user modify ANY environment
+                                                                                                       ; variable!
+safe_mode_protected_env_vars = LD_LIBRARY_PATH         ; This directive contains a comma-
+                                                                                                       ; delimited list of environment variables,
+                                                                                                       ; that the end user won't be able to
+                                                                                                       ; change using putenv().
+                                                                                                       ; These variables will be protected
+                                                                                                       ; even if safe_mode_allowed_env_vars is
+                                                                                                       ; set to allow to change them.
 
 ; Colors for Syntax Highlighting mode.  Anything that's acceptable in <font color=???> would work.
 highlight.string       =       #DD0000