diff options
author | Andrew Dolgov <[email protected]> | 2020-09-14 19:46:52 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2020-09-14 19:46:52 +0300 |
commit | c3d14e1fa54c7dade7b1b7955575e2991396d7ef (patch) | |
tree | adf8415ace77f14bf8042cb518d0c78fecc5baef /classes | |
parent | 5b17fdc36281dd11e4ba0830f368a29aaba134da (diff) |
- fix multiple vulnerabilities in af_proxy_http
- fix vulnerability in rewrite_relative_url() which prevented some URLs from being properly absolutized
- fetch_file_contents: validate all URLs before requesting them
- validate URLs: explicitly whitelist http and https scheme, forbid everything else
- DiskCache/cached_url: only serve whitelisted content types (images, video)
- simplify filename/URL handling code, remove and consolidate some less-used functions
Diffstat (limited to 'classes')
-rw-r--r-- | classes/backend.php | 2 | ||||
-rw-r--r-- | classes/diskcache.php | 6 | ||||
-rwxr-xr-x | classes/feeds.php | 56 | ||||
-rwxr-xr-x | classes/handler/public.php | 2 | ||||
-rwxr-xr-x | classes/pluginhost.php | 2 | ||||
-rwxr-xr-x | classes/pref/feeds.php | 2 | ||||
-rwxr-xr-x | classes/rpc.php | 2 |
7 files changed, 10 insertions, 62 deletions
diff --git a/classes/backend.php b/classes/backend.php index 122e28c65..5bd724728 100644 --- a/classes/backend.php +++ b/classes/backend.php @@ -88,7 +88,7 @@ class Backend extends Handler { } function help() { - $topic = clean_filename($_REQUEST["topic"]); // only one for now + $topic = basename(clean($_REQUEST["topic"])); // only one for now if ($topic == "main") { $info = get_hotkeys_info(); diff --git a/classes/diskcache.php b/classes/diskcache.php index 68829b8e3..74415189c 100644 --- a/classes/diskcache.php +++ b/classes/diskcache.php @@ -191,7 +191,7 @@ class DiskCache { ]; public function __construct($dir) { - $this->dir = CACHE_DIR . "/" . clean_filename($dir); + $this->dir = CACHE_DIR . "/" . basename(clean($dir)); } public function getDir() { @@ -227,9 +227,7 @@ class DiskCache { } public function getFullPath($filename) { - $filename = clean_filename($filename); - - return $this->dir . "/" . $filename; + return $this->dir . "/" . basename(clean($filename)); } public function put($filename, $data) { diff --git a/classes/feeds.php b/classes/feeds.php index 55a514cc0..58ba1b6f8 100755 --- a/classes/feeds.php +++ b/classes/feeds.php @@ -1124,9 +1124,9 @@ class Feeds extends Handler_Protected { $pdo = Db::pdo(); - $url = Feeds::fix_url($url); + $url = validate_url($url); - if (!$url || !Feeds::validate_feed_url($url)) return array("code" => 2); + if (!$url) return array("code" => 2); $contents = @fetch_file_contents($url, false, $auth_login, $auth_pass); @@ -1924,7 +1924,7 @@ class Feeds extends Handler_Protected { } static function get_feeds_from_html($url, $content) { - $url = Feeds::fix_url($url); + $url = validate_url($url); $baseUrl = substr($url, 0, strrpos($url, '/') + 1); $feedUrls = []; @@ -1955,56 +1955,6 @@ class Feeds extends Handler_Protected { return preg_match("/<html|DOCTYPE html/i", substr($content, 0, 8192)) !== 0; } - static function validate_feed_url($url) { - $parts = parse_url($url); - - return ($parts['scheme'] == 'http' || $parts['scheme'] == 'feed' || $parts['scheme'] == 'https'); - } - - /** - * Fixes incomplete URLs by prepending "http://". - * Also replaces feed:// with http://, and - * prepends a trailing slash if the url is a domain name only. - * - * @param string $url Possibly incomplete URL - * - * @return string Fixed URL. - */ - static function fix_url($url) { - - // support schema-less urls - if (strpos($url, '//') === 0) { - $url = 'https:' . $url; - } - - if (strpos($url, '://') === false) { - $url = 'http://' . $url; - } else if (substr($url, 0, 5) == 'feed:') { - $url = 'http:' . substr($url, 5); - } - - //prepend slash if the URL has no slash in it - // "http://www.example" -> "http://www.example/" - if (strpos($url, '/', strpos($url, ':') + 3) === false) { - $url .= '/'; - } - - //convert IDNA hostname to punycode if possible - if (function_exists("idn_to_ascii")) { - $parts = parse_url($url); - if (mb_detect_encoding($parts['host']) != 'ASCII') - { - $parts['host'] = idn_to_ascii($parts['host']); - $url = build_url($parts); - } - } - - if ($url != "http:///") - return $url; - else - return ''; - } - static function add_feed_category($feed_cat, $parent_cat_id = false, $order_id = 0) { if (!$feed_cat) return false; diff --git a/classes/handler/public.php b/classes/handler/public.php index e6d94e223..135cdcbc7 100755 --- a/classes/handler/public.php +++ b/classes/handler/public.php @@ -1234,7 +1234,7 @@ class Handler_Public extends Handler { public function pluginhandler() { $host = new PluginHost(); - $plugin_name = clean_filename($_REQUEST["plugin"]); + $plugin_name = basename(clean($_REQUEST["plugin"])); $method = clean($_REQUEST["pmethod"]); $host->load($plugin_name, PluginHost::KIND_USER, 0); diff --git a/classes/pluginhost.php b/classes/pluginhost.php index 4fec13000..c6c036783 100755 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -193,7 +193,7 @@ class PluginHost { foreach ($plugins as $class) { $class = trim($class); - $class_file = strtolower(clean_filename($class)); + $class_file = strtolower(basename(clean($class))); if (!is_dir(__DIR__."/../plugins/$class_file") && !is_dir(__DIR__."/../plugins.local/$class_file")) continue; diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index 9d29ab478..8cdb1577c 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -1701,7 +1701,7 @@ class Pref_Feeds extends Handler_Protected { foreach ($feeds as $feed) { $feed = trim($feed); - if (Feeds::validate_feed_url($feed)) { + if (validate_url($feed)) { $this->pdo->beginTransaction(); diff --git a/classes/rpc.php b/classes/rpc.php index 208551075..7f809f29b 100755 --- a/classes/rpc.php +++ b/classes/rpc.php @@ -572,7 +572,7 @@ class RPC extends Handler_Protected { function log() { $msg = clean($_REQUEST['msg']); - $file = clean_filename($_REQUEST['file']); + $file = basename(clean($_REQUEST['file'])); $line = (int) clean($_REQUEST['line']); $context = clean($_REQUEST['context']); |