Feature #104470
closedCSP - Report-Only mode
100%
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?
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?
Updated by Oliver Hader 3 months ago
- Related to Feature #101580: Add feature flag to enable CSP ReportOnly mode added
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 existingenforceContentSecurityPolicy
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
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 eitherreport
oreffective
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
andContent-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 existingenforceContentSecurityPolicy
Side-Note: The CSP violation
disposition
property distinguishes betweenenforce
andreport
(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...
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
Updated by Oliver Hader 3 months ago
- Status changed from Needs Feedback to Resolved
Fixed in v12 & v13 with https://review.typo3.org/q/I8c1a8305702629eac1bfedddbecbc19b452fd500