mirror of
https://github.com/php/php-src.git
synced 2025-08-17 22:48:57 +02:00
Add the complement to the putenv() security
This commit is contained in:
parent
1d1b59da76
commit
86a19f4714
4 changed files with 79 additions and 22 deletions
4
NEWS
4
NEWS
|
@ -2,8 +2,8 @@ PHP 4.0 NEWS
|
||||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||
|
|
||||||
?? ?? ????, Version 4.0 Beta 4
|
?? ?? ????, Version 4.0 Beta 4
|
||||||
- Added the ability to prevent the user from overriding certain environment
|
- Added the ability to control the environment variables the user is allowed
|
||||||
variables in Safe Mode (Zeev)
|
to change in Safe Mode, using INI directives (Zeev)
|
||||||
- Fixed a crash bug in strtr() working on large input strings (Zeev)
|
- Fixed a crash bug in strtr() working on large input strings (Zeev)
|
||||||
- Ora_GetColumn()/Ora_FetchInto() now return NULL for NULL-Columns. (Thies)
|
- Ora_GetColumn()/Ora_FetchInto() now return NULL for NULL-Columns. (Thies)
|
||||||
- OCI8 now supports binding of NULL-values. Module cleanups. (Thies)
|
- OCI8 now supports binding of NULL-values. Module cleanups. (Thies)
|
||||||
|
|
|
@ -314,11 +314,11 @@ static PHP_INI_MH(OnUpdateSafeModeProtectedEnvVars)
|
||||||
BLS_FETCH();
|
BLS_FETCH();
|
||||||
|
|
||||||
protected_vars = estrndup(new_value, new_value_length);
|
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, ", ");
|
protected_var=strtok(protected_vars, ", ");
|
||||||
while (protected_var) {
|
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, ", ");
|
protected_var=strtok(NULL, ", ");
|
||||||
}
|
}
|
||||||
efree(protected_vars);
|
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_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()
|
PHP_INI_END()
|
||||||
|
|
||||||
|
|
||||||
|
@ -377,12 +390,16 @@ static void basic_globals_ctor(BLS_D)
|
||||||
{
|
{
|
||||||
BG(next) = NULL;
|
BG(next) = NULL;
|
||||||
BG(left) = -1;
|
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)
|
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();
|
PLS_FETCH();
|
||||||
|
|
||||||
if (PG(safe_mode)) {
|
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);
|
pe.putenv_string = estrndup((*str)->value.str.val,(*str)->value.str.len);
|
||||||
|
@ -547,14 +564,38 @@ PHP_FUNCTION(putenv)
|
||||||
pe.key_len = strlen(pe.key);
|
pe.key_len = strlen(pe.key);
|
||||||
pe.key = estrndup(pe.key,pe.key_len);
|
pe.key = estrndup(pe.key,pe.key_len);
|
||||||
|
|
||||||
if (PG(safe_mode)
|
if (PG(safe_mode)) {
|
||||||
&& zend_hash_exists(&BG(protected_env_vars), pe.key, pe.key_len)) {
|
/* 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);
|
php_error(E_WARNING, "Safe Mode: Cannot override protected environment variable '%s'", pe.key);
|
||||||
efree(pe.putenv_string);
|
efree(pe.putenv_string);
|
||||||
efree(pe.key);
|
efree(pe.key);
|
||||||
RETURN_FALSE;
|
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);
|
zend_hash_del(&BG(putenv_ht),pe.key,pe.key_len+1);
|
||||||
|
|
||||||
/* find previous value */
|
/* find previous value */
|
||||||
|
|
|
@ -136,7 +136,8 @@ typedef struct {
|
||||||
zval **array_walk_func_name;
|
zval **array_walk_func_name;
|
||||||
zval **user_compare_func_name;
|
zval **user_compare_func_name;
|
||||||
|
|
||||||
HashTable protected_env_vars;
|
HashTable sm_protected_env_vars;
|
||||||
|
char *sm_allowed_env_vars;
|
||||||
|
|
||||||
/* pageinfo.c */
|
/* pageinfo.c */
|
||||||
long page_uid;
|
long page_uid;
|
||||||
|
@ -185,5 +186,6 @@ typedef struct {
|
||||||
/* Values are comma-delimited
|
/* 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 */
|
#endif /* _BASIC_FUNCTIONS_H */
|
||||||
|
|
26
php.ini-dist
26
php.ini-dist
|
@ -77,12 +77,26 @@ allow_call_time_pass_reference = On ; whether to enable the ability to force arg
|
||||||
; Safe Mode
|
; Safe Mode
|
||||||
safe_mode = Off
|
safe_mode = Off
|
||||||
safe_mode_exec_dir =
|
safe_mode_exec_dir =
|
||||||
safe_mode_protected_env_vars = LD_LIBRARY_PATH ; In Safe Mode, setting certain environment
|
safe_mode_allowed_env_vars = PHP_ ; Setting certain environment variables
|
||||||
; variables may be a potential security
|
; may be a potential security breach.
|
||||||
; breach. This directive contains
|
; This directive contains a comma-delimited
|
||||||
; a comma delimited list of environment
|
; list of prefixes. In Safe Mode, the
|
||||||
; variables, that the end user won't be
|
; user may only alter environment
|
||||||
; able to override using putenv()
|
; 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.
|
; Colors for Syntax Highlighting mode. Anything that's acceptable in <font color=???> would work.
|
||||||
highlight.string = #DD0000
|
highlight.string = #DD0000
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue