Generic CSP app

When integrating other services such as Element, Discourse or fairmeeting we need to add Content Security Policy exceptions for iFrames. There is a public function for it, which we could put in an app.

This should be a failry simple app, and an AI bot suggests:

Can you write a Nextcloud app to dynamically adjust CSP? Ideally, it offers in the nextcloud administrator security settings a field, where I can enter URLs of domains that require a CSP exception for iframes.

I'll create a Nextcloud app that allows administrators to add CSP iframe-exception domains via the Security Settings in the admin panel. The app will:

  • Add a settings field in Nextcloud Admin Security Settings for entering allowed domains.
  • Dynamically modify the Content Security Policy (CSP) based on the saved domains.
  • Ensure compatibility with Nextcloud’s ContentSecurityPolicyManager for best practices.
<?php
namespace OCA\CSPManager\AppInfo;

use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\DependencyInjection\DIContainer;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\Settings\IManager;
use OCA\CSPManager\Service\CSPService;

class Application extends App implements IBootstrap {
    public const APP_ID = 'cspmanager';

    public function __construct(array $urlParams = []) {
        parent::__construct(self::APP_ID, $urlParams);
    }

    public function register(IManager $manager): void {
        $manager->registerSection(
            'security',
            'CSP Manager',
            'CSP Settings'
        );

        $manager->registerSettings(
            'security',
            [
                'id' => 'cspmanager',
                'name' => 'CSP Domains',
                'type' => 'text',
                'default' => '',
                'description' => 'Enter allowed iframe domains separated by spaces.',
            ]
        );
    }

    public function boot(DIContainer $container): void {
        $cspService = $container->query(CSPService::class);
        $policy = new ContentSecurityPolicy();
        
        foreach ($cspService->getAllowedDomains() as $domain) {
            $policy->addAllowedFrameDomain($domain);
        }

        $container->query('OCP\AppFramework\Http\ContentSecurityPolicyManager')
                  ->addDefaultPolicy($policy);
    }
}

@philipp.monz could you review this proposal?

Edited by Roland Alton
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information