diff options
-rw-r--r-- | includes/file.inc | 19 | ||||
-rw-r--r-- | modules/upload.module | 9 | ||||
-rw-r--r-- | modules/upload/upload.module | 9 |
3 files changed, 35 insertions, 2 deletions
diff --git a/includes/file.inc b/includes/file.inc index eccdb2fc7..2c3e8a5ec 100644 --- a/includes/file.inc +++ b/includes/file.inc @@ -27,6 +27,11 @@ define('FILE_EXISTS_ERROR', 2); * @return A string containing a URL that can be used to download the file. */ function file_create_url($path) { + // strip file_directory_paths from url if present. Prevent ugly and filesystem revealing + // urls like http://example.com/system/files/../../../home/gatsby/private/files + // I think it also keep absolute file_directory_paths working since they would get broken if + // we tried to pass them in the url. + if (strpos($path, file_directory_path()) !== false) { $path = trim(substr($path, strlen(file_directory_path())), '\\/'); } @@ -34,7 +39,7 @@ function file_create_url($path) { case FILE_DOWNLOADS_PUBLIC: return $GLOBALS['base_url'] .'/'. file_directory_path() .'/'. str_replace('\\', '/', $path); case FILE_DOWNLOADS_PRIVATE: - return url('system/files', 'file='. $path, NULL, TRUE); + return url('system/files/'. $path, NULL, NULL, TRUE); } } @@ -573,7 +578,17 @@ function file_transfer($source, $headers) { */ function file_download() { - $filepath = $_GET['file']; + //use the remainder of the path to get the file. + //enables 4.7 clean private files paths. + $args = func_get_args(); + $filepath = implode('/', $args); + + // add the ?file= if it is present. Otherwise we + // break all old nodes with private files displayed + // inline. + if (isset($_GET['file'])) { + $filepath = $_GET['file']; + } if (file_exists(file_create_path($filepath))) { $headers = module_invoke_all('file_download', $filepath); diff --git a/modules/upload.module b/modules/upload.module index 000c5ae15..d55afb6b2 100644 --- a/modules/upload.module +++ b/modules/upload.module @@ -79,6 +79,15 @@ function upload_menu($may_cache) { if ($_SESSION['file_previews']) { foreach ($_SESSION['file_previews'] as $fid => $file) { $filename = file_create_filename($file->filename, file_create_path()); + if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PRIVATE) { + // strip file_directory_path() from filepath + // to hide relative paths in url. see file_create_url + if (strpos($filename, file_directory_path()) !== false) { + $filename = trim(substr($filename, strlen(file_directory_path())), '\\/'); + } + $filename = 'system/files/' . $filename; + } + $items[] = array( 'path' => $filename, 'title' => t('file download'), 'callback' => 'upload_download', diff --git a/modules/upload/upload.module b/modules/upload/upload.module index 000c5ae15..d55afb6b2 100644 --- a/modules/upload/upload.module +++ b/modules/upload/upload.module @@ -79,6 +79,15 @@ function upload_menu($may_cache) { if ($_SESSION['file_previews']) { foreach ($_SESSION['file_previews'] as $fid => $file) { $filename = file_create_filename($file->filename, file_create_path()); + if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PRIVATE) { + // strip file_directory_path() from filepath + // to hide relative paths in url. see file_create_url + if (strpos($filename, file_directory_path()) !== false) { + $filename = trim(substr($filename, strlen(file_directory_path())), '\\/'); + } + $filename = 'system/files/' . $filename; + } + $items[] = array( 'path' => $filename, 'title' => t('file download'), 'callback' => 'upload_download', |