From eb54143c2d6ccc9ad4220207f1be617abb6e71e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Sun, 28 Sep 2025 22:27:18 +0200 Subject: [PATCH] fix: Delete legacy OC_Response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moved the last used method in base.php where it’s called. Ideally we would remove it but it’s not clear whether that would be possible any time soon or even at all. Signed-off-by: Côme Chilliet --- lib/base.php | 37 ++++++++- lib/composer/composer/autoload_classmap.php | 1 - lib/composer/composer/autoload_static.php | 1 - lib/private/legacy/OC_Response.php | 83 --------------------- 4 files changed, 36 insertions(+), 86 deletions(-) delete mode 100644 lib/private/legacy/OC_Response.php diff --git a/lib/base.php b/lib/base.php index fb3794aa8ec17..b890cdb6dd74f 100644 --- a/lib/base.php +++ b/lib/base.php @@ -579,6 +579,41 @@ private static function performSameSiteCookieProtection(IConfig $config): void { } } + /** + * This function adds some security related headers to all requests served via base.php + * The implementation of this function has to happen here to ensure that all third-party + * components (e.g. SabreDAV) also benefit from this headers. + */ + private static function addSecurityHeaders(): void { + /** + * FIXME: Content Security Policy for legacy components. This + * can be removed once \OCP\AppFramework\Http\Response from the AppFramework + * is used everywhere. + * @see \OCP\AppFramework\Http\Response::getHeaders + */ + $policy = 'default-src \'self\'; ' + . 'script-src \'self\' \'nonce-' . \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() . '\'; ' + . 'style-src \'self\' \'unsafe-inline\'; ' + . 'frame-src *; ' + . 'img-src * data: blob:; ' + . 'font-src \'self\' data:; ' + . 'media-src *; ' + . 'connect-src *; ' + . 'object-src \'none\'; ' + . 'base-uri \'self\'; '; + header('Content-Security-Policy:' . $policy); + + // Send fallback headers for installations that don't have the possibility to send + // custom headers on the webserver side + if (getenv('modHeadersAvailable') !== 'true') { + header('Referrer-Policy: no-referrer'); // https://www.w3.org/TR/referrer-policy/ + header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE + header('X-Frame-Options: SAMEORIGIN'); // Disallow iFraming from other domains + header('X-Permitted-Cross-Domain-Policies: none'); // https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html + header('X-Robots-Tag: noindex, nofollow'); // https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag + } + } + public static function init(): void { // First handle PHP configuration and copy auth headers to the expected // $_SERVER variable before doing anything Server object related @@ -702,7 +737,7 @@ public static function init(): void { self::checkConfig(); self::checkInstalled($systemConfig); - OC_Response::addSecurityHeaders(); + self::addSecurityHeaders(); self::performSameSiteCookieProtection($config); diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index e7251e78f81a8..ee77fbd4cda82 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -2179,7 +2179,6 @@ 'OC_Helper' => $baseDir . '/lib/private/legacy/OC_Helper.php', 'OC_Hook' => $baseDir . '/lib/private/legacy/OC_Hook.php', 'OC_JSON' => $baseDir . '/lib/private/legacy/OC_JSON.php', - 'OC_Response' => $baseDir . '/lib/private/legacy/OC_Response.php', 'OC_Template' => $baseDir . '/lib/private/legacy/OC_Template.php', 'OC_User' => $baseDir . '/lib/private/legacy/OC_User.php', 'OC_Util' => $baseDir . '/lib/private/legacy/OC_Util.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 45c9221f8f4e2..3b18f00da9697 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -2220,7 +2220,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC_Helper' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Helper.php', 'OC_Hook' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Hook.php', 'OC_JSON' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_JSON.php', - 'OC_Response' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Response.php', 'OC_Template' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Template.php', 'OC_User' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_User.php', 'OC_Util' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Util.php', diff --git a/lib/private/legacy/OC_Response.php b/lib/private/legacy/OC_Response.php deleted file mode 100644 index c45852b4b1d22..0000000000000 --- a/lib/private/legacy/OC_Response.php +++ /dev/null @@ -1,83 +0,0 @@ -getRequest()->isUserAgent( - [ - \OC\AppFramework\Http\Request::USER_AGENT_IE, - \OC\AppFramework\Http\Request::USER_AGENT_ANDROID_MOBILE_CHROME, - \OC\AppFramework\Http\Request::USER_AGENT_FREEBOX, - ])) { - header('Content-Disposition: ' . rawurlencode($type) . '; filename="' . rawurlencode($filename) . '"'); - } else { - header('Content-Disposition: ' . rawurlencode($type) . '; filename*=UTF-8\'\'' . rawurlencode($filename) - . '; filename="' . rawurlencode($filename) . '"'); - } - } - - /** - * Sets the content length header (with possible workarounds) - * @param string|int|float $length Length to be sent - */ - public static function setContentLengthHeader($length) { - if (PHP_INT_SIZE === 4) { - if ($length > PHP_INT_MAX && stripos(PHP_SAPI, 'apache') === 0) { - // Apache PHP SAPI casts Content-Length headers to PHP integers. - // This enforces a limit of PHP_INT_MAX (2147483647 on 32-bit - // platforms). So, if the length is greater than PHP_INT_MAX, - // we just do not send a Content-Length header to prevent - // bodies from being received incompletely. - return; - } - // Convert signed integer or float to unsigned base-10 string. - $lfh = new \OC\LargeFileHelper; - $length = $lfh->formatUnsignedInteger($length); - } - header('Content-Length: ' . $length); - } - - /** - * This function adds some security related headers to all requests served via base.php - * The implementation of this function has to happen here to ensure that all third-party - * components (e.g. SabreDAV) also benefit from this headers. - */ - public static function addSecurityHeaders() { - /** - * FIXME: Content Security Policy for legacy ownCloud components. This - * can be removed once \OCP\AppFramework\Http\Response from the AppFramework - * is used everywhere. - * @see \OCP\AppFramework\Http\Response::getHeaders - */ - $policy = 'default-src \'self\'; ' - . 'script-src \'self\' \'nonce-' . \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() . '\'; ' - . 'style-src \'self\' \'unsafe-inline\'; ' - . 'frame-src *; ' - . 'img-src * data: blob:; ' - . 'font-src \'self\' data:; ' - . 'media-src *; ' - . 'connect-src *; ' - . 'object-src \'none\'; ' - . 'base-uri \'self\'; '; - header('Content-Security-Policy:' . $policy); - - // Send fallback headers for installations that don't have the possibility to send - // custom headers on the webserver side - if (getenv('modHeadersAvailable') !== 'true') { - header('Referrer-Policy: no-referrer'); // https://www.w3.org/TR/referrer-policy/ - header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE - header('X-Frame-Options: SAMEORIGIN'); // Disallow iFraming from other domains - header('X-Permitted-Cross-Domain-Policies: none'); // https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html - header('X-Robots-Tag: noindex, nofollow'); // https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag - } - } -}