Sfoglia il codice sorgente

Fix security hole from ext.php script.

Now, ext.php can only serve file under a EXTENSIONS_PATH/ext_dir/static/ directory.
A 400 Bad Request error will be returned for other files.

See https://github.com/FreshRSS/FreshRSS/issues/252
And https://github.com/FreshRSS/FreshRSS/commit/f9b037742a0aeb49cab86782d1a59913c2de47b
Marien Fressinaud 11 anni fa
parent
commit
a2da70fd11
2 ha cambiato i file con 35 aggiunte e 3 eliminazioni
  1. 2 2
      lib/Minz/Extension.php
  2. 33 1
      p/ext.php

+ 2 - 2
lib/Minz/Extension.php

@@ -106,9 +106,9 @@ class Minz_Extension {
 	 */
 	public function getFileUrl($filename, $type) {
 		$dir = end(explode('/', $this->path));
-		$file_name_url = urlencode($dir . '/' . $filename);
+		$file_name_url = urlencode($dir . '/static/' . $filename);
 
-		$absolute_path = $this->path . '/' . $filename;
+		$absolute_path = $this->path . '/static/' . $filename;
 		$mtime = @filemtime($absolute_path);
 
 		$url = '/ext.php?f=' . $file_name_url .

+ 33 - 1
p/ext.php

@@ -7,10 +7,42 @@ if (!isset($_GET['f']) ||
 
 require('../constants.php');
 
+/**
+ * Check if a file can be served by ext.php. A valid file is under a
+ * EXTENSIONS_PATH/extension_name/static/ directory.
+ *
+ * You should sanitize path by using the realpath() function.
+ *
+ * @param $path the path to the file we want to serve.
+ * @return true if it can be served, false else.
+ *
+ */
+function is_valid_path($path) {
+	// It must be under the extension path.
+	$in_ext_path = (substr($path, 0, strlen(EXTENSIONS_PATH)) === EXTENSIONS_PATH);
+	if (!$in_ext_path) {
+		return false;
+	}
+
+	// File to serve must be under a `ext_dir/static/` directory.
+	$path_relative_to_ext = substr($path, strlen(EXTENSIONS_PATH) + 1);
+	$path_splitted = explode('/', $path_relative_to_ext);
+	if (count($path_splitted) < 3 || $path_splitted[1] !== 'static') {
+		return false;
+	}
+
+	return true;
+}
+
 $file_name = urldecode($_GET['f']);
 $file_type = $_GET['t'];
 
-$absolute_filename = EXTENSIONS_PATH . '/' . $file_name;
+$absolute_filename = realpath(EXTENSIONS_PATH . '/' . $file_name);
+
+if (!is_valid_path($absolute_filename)) {
+	header('HTTP/1.1 400 Bad Request');
+	die();
+}
 
 switch ($file_type) {
 case 'css':