diff options
| author | 2025-04-07 08:47:42 +0200 | |
|---|---|---|
| committer | 2025-04-07 08:47:42 +0200 | |
| commit | 0c33d2713957eaf6cc0222150df7ebbcb53beaed (patch) | |
| tree | a9a011c370e2d8ecf3c3290dfb1afd86c9cea0bc /app | |
| parent | d3d9acca9f905fc03d6151f6ad75567256310831 (diff) | |
Secure serving of user files from extensions (#7495)
* Secure serving of user files from extensions
fix https://github.com/FreshRSS/FreshRSS/issues/4930
* More fixes
* Typo
Diffstat (limited to 'app')
| -rw-r--r-- | app/Controllers/extensionController.php | 36 | ||||
| -rw-r--r-- | app/views/extension/serve.phtml | 0 |
2 files changed, 36 insertions, 0 deletions
diff --git a/app/Controllers/extensionController.php b/app/Controllers/extensionController.php index f08013e7d..5afa43bd8 100644 --- a/app/Controllers/extensionController.php +++ b/app/Controllers/extensionController.php @@ -298,4 +298,40 @@ class FreshRSS_extension_Controller extends FreshRSS_ActionController { Minz_Request::forward($url_redirect, true); } + + // Supported types with their associated content type + public const MIME_TYPES = [ + 'css' => 'text/css; charset=UTF-8', + 'gif' => 'image/gif', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'js' => 'application/javascript; charset=UTF-8', + 'png' => 'image/png', + 'svg' => 'image/svg+xml', + ]; + + public function serveAction(): void { + $extensionName = Minz_Request::paramString('x'); + $filename = Minz_Request::paramString('f'); + $mimeType = pathinfo($filename, PATHINFO_EXTENSION); + if ($extensionName === '' || $filename === '' || $mimeType === '' || empty(self::MIME_TYPES[$mimeType])) { + header('HTTP/1.1 400 Bad Request'); + die('Bad Request!'); + } + $extension = Minz_ExtensionManager::findExtension($extensionName); + if ($extension === null || !$extension->isEnabled() || ($mtime = $extension->mtimeFile($filename)) === null) { + header('HTTP/1.1 404 Not Found'); + die('Not Found!'); + } + + $this->view->_layout(null); + + $content_type = self::MIME_TYPES[$mimeType]; + header("Content-Type: {$content_type}"); + header("Content-Disposition: inline; filename='{$filename}'"); + header('Referrer-Policy: same-origin'); + if (!httpConditional($mtime, cacheSeconds: 604800, cachePrivacy: 2)) { + echo $extension->getFile($filename); + } + } } diff --git a/app/views/extension/serve.phtml b/app/views/extension/serve.phtml new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/app/views/extension/serve.phtml |
