Release: CVS tree 2001-03-21 and php4.0.4-pl1 Some remarks about missed funzionality and bugs fopen function, even in read mode miserably fails on any file not owned by the script owner even if the the web server process owner has read permissions, on it. As any file created by php is owned by this process, it can make any file created by the web server process unreadable. It makes usage of file uploads only good with database blobs. copy function only checks permission on the source, not the target, so again the user can overwrite any file owned by the owner of the web server process. similarly move_uploaded_file do not check for target ownership. with the patch enclosed in the message (can be applied against current cvs release) all the above problems seem to be solved. If you don't like to give even read access to the files, keeping the actual policy, remove the patch concerning the safe_mode.c file About safe mode operations a good way to improve security without loosing usabilty could be to parametrize in php.ini a minimum uid of the owner of the directory you want to give even read only access in safe mode. So the auth process would be: give access to a file in read only mode if: 1) is a uploaded_file 2) it is owned by wwwrun and the directory it resides is owned by the script owner or by an uid greather then safe_mode_minduid. give write access to a file only if 1) it is owned by wwwrun or by the script uid (obviously writable also by wwwrun) and it resides in a directory owned by the script uid. diff -ur /root/php4/ext/standard/basic_functions.c php-4.0.4pl1/ext/standard/basic_functions.c --- /root/php4/ext/standard/basic_functions.c Wed Mar 21 14:53:38 2001 +++ php-4.0.4pl1/ext/standard/basic_functions.c Thu Mar 22 15:31:19 2001 @@ -2490,7 +2490,11 @@ if (!zend_hash_exists(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path), Z_STRLEN_PP(path)+1)) { RETURN_FALSE; } - + + if (PG(safe_mode) &&(!php_checkuid(Z_STRVAL_PP(new_path), NULL, CHECKUID_CHECK_FILE_AND_DIR))) { + RETURN_FALSE; + } + V_UNLINK(Z_STRVAL_PP(new_path)); if (rename(Z_STRVAL_PP(path), Z_STRVAL_PP(new_path))==0) { successful=1; diff -ur /root/php4/ext/standard/file.c php-4.0.4pl1/ext/standard/file.c --- /root/php4/ext/standard/file.c Sun Mar 11 11:08:27 2001 +++ php-4.0.4pl1/ext/standard/file.c Thu Mar 22 15:24:18 2001 @@ -1691,7 +1691,7 @@ { pval **source, **target; PLS_FETCH(); - + if (ARG_COUNT(ht) != 2 || zend_get_parameters_ex(2, &source, &target) == FAILURE) { WRONG_PARAM_COUNT; } @@ -1702,7 +1702,11 @@ if (PG(safe_mode) &&(!php_checkuid((*source)->value.str.val, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { RETURN_FALSE; } - + + if (PG(safe_mode) &&(!php_checkuid((*target)->value.str.val, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { + RETURN_FALSE; + } + if (php_copy_file(Z_STRVAL_PP(source), Z_STRVAL_PP(target))==SUCCESS) { RETURN_TRUE; } else { diff -ur /root/php4/main/safe_mode.c php-4.0.4pl1/main/safe_mode.c --- /root/php4/main/safe_mode.c Mon Feb 26 07:07:31 2001 +++ php-4.0.4pl1/main/safe_mode.c Thu Mar 22 15:24:18 2001 @@ -47,6 +47,7 @@ struct stat sb; int ret; long uid=0L, duid=0L; + int writemode = 0; char *s; if (!filename) { @@ -56,6 +57,8 @@ if (fopen_mode) { if (fopen_mode[0] == 'r') { mode = CHECKUID_DISALLOW_FILE_NOT_EXISTS; + for (ret=0 ; (fopen_mode[ret]!='\0' && writemode == 0) ; ret++) + writemode = (fopen_mode[ret] == '+' ? 1 : 0); } else { mode = CHECKUID_CHECK_FILE_AND_DIR; } @@ -81,7 +84,7 @@ } } else { uid = sb.st_uid; - if (uid == php_getuid()) { + if (uid == php_getuid() || ( uid == getuid() && mode == CHECKUID_DISALLOW_FILE_NOT_EXISTS && writemode == 0)) { return 1; } } -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] To contact the list administrators, e-mail: [EMAIL PROTECTED]