Project

General

Profile

Actions

Feature #104470

closed

CSP - Report-Only mode

Added by cosmoblonde GmbH 4 months ago. Updated about 1 month ago.

Status:
Closed
Priority:
Should have
Assignee:
Category:
Content Security Policy
Target version:
-
Start date:
2024-07-24
Due date:
% Done:

100%

Estimated time:
PHP Version:
8.2
Tags:
Complexity:
Sprint Focus:

Description

Implementing a proper CSP for a complex TYPO3 site using many external sources, scripts and stuff is a nasty and timeconsuming task.

So although it's great that CSP violations can be tracked with TYPO3 in the CSP BE module - it would be good if a Report-Only Tracking could be set via configuration. So a website can run a while in reporting-mode and you can collect the issues and fix them.

We do not find any configuration flags that would enable a Report-Only mode.

You can turn on
SYS.features.security.backend.enforceContentSecurityPolicy
and/or
SYS.features.security.frontend.enforceContentSecurityPolicy

but this does directly activate the CSP - so the FE may become unusable and this is not suitable for a live site.

Or is this already possible and we have just missed the respective documentation?


Related issues 1 (0 open1 closed)

Related to TYPO3 Core - Feature #101580: Add feature flag to enable CSP ReportOnly modeClosedOliver Hader2023-08-04

Actions
Actions #1

Updated by Garvin Hicking 4 months ago

  • Category changed from Security to Content Security Policy
  • Status changed from New to Needs Feedback

Indeed I couldn't see an option to use the "Content-Security-Policy-Report-Only" header. typo3/sysext/frontend/Classes/Middleware/ContentSecurityPolicyHeaders.php in method process does this:

return $response->withHeader('Content-Security-Policy', $policy->compile($this->requestId->nonce, $this->cache));

so there's no toggle for the header. While this would be nice to get implemented as a flag, you could workaround this with a small hack.

You could register a custom middleware just after the ContentSecurityPolicyHeaders middleware and modify the output with something like:

final readonly class ContentSecurityPolicyHeadersReportOnly implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $response = $handler->handle($request);
        // ContentSecurityPolicyHeaders has now handled our response, let's mangle it.
        if ($response->hasHeader('Content-Security-Policy')) {
            $response = $response->withHeader('Content-Security-Policy-Report-Only', $response->getHeader('Content-Security-Policy'));
            // Detach the old header
            $response = $response->withoutHeader('Content-Security-Policy');
        }
        return $response;
    }
}

I have not tested this, but in theory this should work by just "renaming" the header. Maybe you'd like to try this until a decision can be made whether to support this with a config/option/API toggle?

Actions #2

Updated by Oliver Hader 3 months ago

  • Related to Feature #101580: Add feature flag to enable CSP ReportOnly mode added
Actions #3

Updated by Oliver Hader 3 months ago

Issue #101580 has a patch for using Content-Security-Policy-Report-Only (as a binary decision, thus either report or effective CSP mode).

However, when testing modifications to an existing Content-Security-Policy, it seems to be useful, to have both headers with different directives at the same time - Content-Security-Policy and Content-Security-Policy-Report-Only. That's why I'm proposing the following:

  • introduce new sites/my-site/csp-report-only.yaml (for a site-specific report-only configuration)
  • introduce new Configuration/ContentSecurityPoliciesReportOnly.php (for a package-specific report-only configuration)
  • handle the additional scope for Content-Security-Policy-Report-Only separated in the existing middlewares
  • (maybe) add a feature flag reportContentSecurityPolicy next to the existing enforceContentSecurityPolicy

Side-Note: The CSP violation disposition property distinguishes between enforce and report (maybe to be considered in the names mentioned above) → see https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP#disposition

Actions #4

Updated by Oliver Hader 3 months ago

Oliver Hader wrote in #note-3:

Issue #101580 has a patch for using Content-Security-Policy-Report-Only (as a binary decision, thus either report or effective CSP mode).

However, when testing modifications to an existing Content-Security-Policy, it seems to be useful, to have both headers with different directives at the same time - Content-Security-Policy and Content-Security-Policy-Report-Only. That's why I'm proposing the following:

  • introduce new sites/my-site/csp-report-only.yaml (for a site-specific report-only configuration)
  • introduce new Configuration/ContentSecurityPoliciesReportOnly.php (for a package-specific report-only configuration)
  • handle the additional scope for Content-Security-Policy-Report-Only separated in the existing middlewares
  • (maybe) add a feature flag reportContentSecurityPolicy next to the existing enforceContentSecurityPolicy

Side-Note: The CSP violation disposition property distinguishes between enforce and report (maybe to be considered in the names mentioned above) → see https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP#disposition

Albeit it looks good, to keep things that separated - it would introduce lots of new challenges - e.g. moving a CSP declaration of some 3rd party extension in the effective scope to a temporary report scoped... hm...

Actions #5

Updated by Oliver Hader 3 months ago

An alternative approach might be to make `sites/my-site/csp.yaml` to be the aggregation instance for any CSP rules for a particular site (with the implication that there always has to be a site configured)

enforce: true
mutations:
 - ...

→ us all CSP mutations and enforce them using the regular Content-Security-Policy header


enforce:
  packages:
    '*': false
    'typo3/cms-frontend': true
    'vendor/any-other-extension': true
  mutations:
   - ...

→ only us the listed packages to compose the Content-Security-Policy header


enforce:
  packages:
    '*': true
    'vendor/any-other-extension': false
  mutations:
   - ...
report:
  packages:
    '*': true
    'vendor/any-other-extension': true
  mutations:
   - ...

→ using all packages except vendor/any-other-extension for Content-Security-Policy header, and having all packages including vendor/any-other-extension for Content-Security-Policy-Report-Only (the explicit reference to 'vendor/any-other-extension': true is not required, just to make it visible)


disable: true
mutations:
 - ...

→ completely disables any CSP header for a specific site

Actions #6

Updated by Oliver Hader 3 months ago

  • Status changed from Needs Feedback to Resolved
Actions #7

Updated by Oliver Hader 3 months ago

  • % Done changed from 0 to 100
Actions #8

Updated by Benni Mack about 1 month ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF