php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #46888 copy() : safe_mode / allow_url_fopen does not allow opening urls
Submitted: 2008-12-17 14:17 UTC Modified: 2015-08-27 14:26 UTC
Votes:17
Avg. Score:4.1 ± 0.8
Reproduced:12 of 12 (100.0%)
Same Version:5 (41.7%)
Same OS:4 (33.3%)
From: php at degoulet dot net Assigned: cmb (profile)
Status: Closed Package: Safe Mode/open_basedir
PHP Version: 5.2.9 OS: *
Private report: No CVE-ID: None
 [2008-12-17 14:17 UTC] php at degoulet dot net
Description:
------------
copy() does not use the allow_url_fopen status ?

Reproduce code:
---------------
<?php
// Fonction copie distante ne fonctionnant plus
copy("http://www.xxxxxx.com/testcopy/nok.jpg", "nok_copy.jpg");
?>

Expected result:
----------------
works fine in php 5.2.6 : with allow_url_fopen = On & safe_mode = On
doesn't work with the same config php 5.2.8

now, it works only if safe_mode off ?



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-12-17 14:44 UTC] php at degoulet dot net
error msg :

Warning: copy(): Unable to access http://www.xxxxx.com/testcopy/nok.jpg in /............/test.php
 [2008-12-17 14:58 UTC] christian at elmerot dot se
The following patch restores part of behaviour from 5.2.6 yet has an extra check to see if the URL contains "../" which is where the removal came from. It is not a 100% correct "fix" in that it still allows for unknown URL vectors to bypass safe_mode, however, it is less broken this way for us. Perhaps the patch will help someone else.

Remember, this is a safe_mode bypass issue that was fixed and the underlying cause (URLs: http: mapping to a local file incorrectly) looks to me unfixed. To me it looks as if safe_mode fails in this case but it also do no "extra" harm that won't be allowed with safe_mode disabled. Have I missed something?

diff -Nur php-5.2.8/main/safe_mode.c php-5.2.8_1/main/safe_mode.c
--- php-5.2.8/main/safe_mode.c	2008-07-24 18:01:59.000000000 +0200
+++ php-5.2.8_1/main/safe_mode.c	2008-12-17 15:01:07.502862702 +0100
@@ -52,6 +52,7 @@
 	long uid=0L, gid=0L, duid=0L, dgid=0L;
 	char path[MAXPATHLEN];
 	char *s, filenamecopy[MAXPATHLEN];
+	php_stream_wrapper *wrapper = NULL;
 	TSRMLS_FETCH();
 
 	path[0] = '\0';
@@ -72,6 +73,15 @@
 			mode = CHECKUID_CHECK_FILE_AND_DIR;
 		}
 	}
+
+	/* 
+	 * If given filepath is a URL, allow - safe mode stuff
+	 * related to URL's is checked in individual functions
+        * Possibly/likely allows for safe_mode bypass!!!
+	 */
+	wrapper = php_stream_locate_url_wrapper(filename, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC);
+	if ((wrapper != NULL) && (strstr(filename, "..\/") == NULL))
+		return 1;
 		
 	/* First we see if the file is owned by the same user...
 	 * If that fails, passthrough and check directory...
 [2008-12-17 15:22 UTC] php at degoulet dot net
thanks : this workaround works fine !
 [2009-03-12 13:44 UTC] fuxa_kos at unihost dot cz
problem still in 5.2.9
 [2009-04-28 13:32 UTC] neo at nord-style dot com
Hello, I've the same problem but I don't understand how use this patch. Actually safe_mode off but it's not a solution.

How and Where Am i use this :
---------------
diff -Nur php-5.2.8/main/safe_mode.c php-5.2.8_1/main/safe_mode.c
--- php-5.2.8/main/safe_mode.c	2008-07-24 18:01:59.000000000 +0200
+++ php-5.2.8_1/main/safe_mode.c	2008-12-17 15:01:07.502862702 +0100
@@ -52,6 +52,7 @@
 	long uid=0L, gid=0L, duid=0L, dgid=0L;
 	char path[MAXPATHLEN];
 	char *s, filenamecopy[MAXPATHLEN];
+	php_stream_wrapper *wrapper = NULL;
 	TSRMLS_FETCH();
 
 	path[0] = '\0';
@@ -72,6 +73,15 @@
 			mode = CHECKUID_CHECK_FILE_AND_DIR;
 		}
 	}
+
+	/* 
+	 * If given filepath is a URL, allow - safe mode stuff
+	 * related to URL's is checked in individual functions
+        * Possibly/likely allows for safe_mode bypass!!!
+	 */
+	wrapper = php_stream_locate_url_wrapper(filename, NULL,
STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC);
+	if ((wrapper != NULL) && (strstr(filename, "..\/") == NULL))
+		return 1;
 		
 	/* First we see if the file is owned by the same user...
 	 * If that fails, passthrough and check directory...
---------------

Thx
 [2009-05-15 14:04 UTC] christian at elmerot dot se
You apply the patch using the command patch when you build PHP from the sourcecode. If you've never done this before I cannot recommend that you do this for something like PHP.

If you still go ahead, download the PHP sourcecode, extract it and read the files (README and INSTALL). Check documentation for using the patch command (man patch). in general you save the patch to a file (lets call it safemode.patch) then you simply run "patch main/safe_mode.c < safemode.patch" in the folder where you unpacked the source
 [2009-09-01 16:21 UTC] sjoerd@php.net
Could reproduce. With safe mode, files which are handled by stream wrappers are checked against the filesystem. This is wrong.
 [2011-05-20 02:32 UTC] macmiranda at gmail dot com
same on centos 5.5 php 5.2.17
 [2011-11-09 14:58 UTC] czigor at freemail dot hu
Same here on php 5.2.17, Linux blue 2.6.37-fw2.
 [2012-05-25 12:31 UTC] maurice dot sienema at isp dot solcon dot nl
I can reproduce this issue on PHP 5.3.13
 [2015-08-27 14:26 UTC] cmb@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: cmb
 [2015-08-27 14:26 UTC] cmb@php.net
As of PHP 5.4.0 the safe mode "feature" has been removed, so this
ticket can be closed.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Thu Oct 17 23:01:27 2019 UTC