>|\/>)/';
- }
-
- private static function buildMatchAttributeNameWithAnyValueReqex(
- string $name
- ): string {
- $nameQuoted = self::escapeReqexCharsInString($name);
-
- return '/(?<.*? )(?'.
- $nameQuoted.
- ')(?=")(?.*?)(?".*?>)/';
- }
-
- private static function buildMatchAttributeNameReqex(string $name): string
- {
- $nameQuoted = self::escapeReqexCharsInString($name);
-
- return '/(?<.*? )(?'.$nameQuoted.')(?.*?>)/';
- }
-
- private static function buildMatchAttributeNameWithSpecificValueReqex(
- string $name,
- string $value
- ): string {
- $nameQuoted = self::escapeReqexCharsInString($name);
- $valueQuoted = self::escapeReqexCharsInString($value);
-
- return '/(?<.*? )(?'.
- $nameQuoted.
- ')(?=")(?'.
- $valueQuoted.
- ')(?".*?>)/';
- }
-}
diff --git a/Flowpack.ContentSecurityPolicy/Classes/Http/CspHeaderMiddleware.php b/Flowpack.ContentSecurityPolicy/Classes/Http/CspHeaderMiddleware.php
deleted file mode 100644
index 66b5245..0000000
--- a/Flowpack.ContentSecurityPolicy/Classes/Http/CspHeaderMiddleware.php
+++ /dev/null
@@ -1,144 +0,0 @@
-handle($request);
- if (!$this->enabled) {
- return $response;
- }
-
- try {
- $policy = $this->getPolicyByCurrentContext($request);
- } catch (Exception $exception) {
- $this->logger->critical($exception->getMessage(), ['exception' => $exception]);
-
- return $response;
- }
-
- if ($policy->hasNonceDirectiveValue()) {
- $body = $response->getBody();
- $newBody = $this->addNonceToTags((string)$body);
- $body = Utils::streamFor($newBody);
- $response = $response->withBody($body);
- }
-
- return $response->withAddedHeader($policy->getSecurityHeaderKey(), (string)$policy);
- }
-
- /**
- * @throws InvalidDirectiveException
- */
- private function getPolicyByCurrentContext(ServerRequestInterface $request): Policy
- {
- /*
- * There is no other way to know if we're in the backend here, we cannot inject
- * Neos\Neos\Domain\Service\ContentContext at this point as it throws an error.
- */
- if (str_starts_with($request->getUri()->getPath(), '/neos')) {
- return PolicyFactory::create(
- $this->nonce,
- $this->configuration['backend'],
- $this->configuration['custom-backend']
- );
- }
-
- return PolicyFactory::create(
- $this->nonce,
- $this->configuration['default'],
- $this->configuration['custom']
- );
- }
-
-
- private function addNonceToTags(string $markup): string
- {
- $tagNames = ['script', 'style'];
-
- return $this->checkTagAndReplaceUsingACallback($tagNames, $markup, function (
- $tagMarkup,
- ) {
- if (TagHelper::tagHasAttribute($tagMarkup, TagHelper::NONCE)) {
- return TagHelper::tagChangeAttributeValue($tagMarkup, TagHelper::NONCE, $this->nonce->getValue());
- }
-
- return TagHelper::tagAddAttribute($tagMarkup, TagHelper::NONCE, $this->nonce->getValue());
- });
- }
-
- /**
- * @param string[] $tagNames
- * @param string $contentMarkup
- * @param callable $hitCallback
- * @return string
- */
- private function checkTagAndReplaceUsingACallback(
- array $tagNames,
- string $contentMarkup,
- callable $hitCallback
- ): string {
- $regex = '/<('.implode('|', $tagNames).').*?>/';
-
- return preg_replace_callback(
- $regex,
- function ($hits) use ($hitCallback, $tagNames) {
- $tagMarkup = $hits[0];
- $tagName = $hits[1];
-
- if (! $hitCallback) {
- return $tagMarkup;
- }
-
- return call_user_func(
- $hitCallback,
- $tagMarkup,
- $tagName
- );
- },
- $contentMarkup
- );
- }
-}
diff --git a/Flowpack.ContentSecurityPolicy/Classes/Model/Directive.php b/Flowpack.ContentSecurityPolicy/Classes/Model/Directive.php
deleted file mode 100644
index 28ce135..0000000
--- a/Flowpack.ContentSecurityPolicy/Classes/Model/Directive.php
+++ /dev/null
@@ -1,45 +0,0 @@
-value = $this->generateNonce();
- }
-
- public function getValue(): string
- {
- return $this->value;
- }
-
- public function __toString()
- {
- return $this->value;
- }
-
- /**
- * @throws Exception
- */
- private function generateNonce(): string
- {
- $string = '';
-
- while (($currentLength = strlen($string)) < self::NONCE_LENGTH) {
- $size = 16 - $currentLength;
-
- $bytes = random_bytes($size);
-
- $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
- }
-
- return $string;
- }
-}
diff --git a/Flowpack.ContentSecurityPolicy/Classes/Model/Policy.php b/Flowpack.ContentSecurityPolicy/Classes/Model/Policy.php
deleted file mode 100644
index 16ace5d..0000000
--- a/Flowpack.ContentSecurityPolicy/Classes/Model/Policy.php
+++ /dev/null
@@ -1,120 +0,0 @@
-nonce = $nonce;
-
- return $this;
- }
-
- public function isReportOnly(): bool
- {
- return $this->reportOnly;
- }
-
- public function getSecurityHeaderKey(): string
- {
- if ($this->isReportOnly()) {
- return self::SECURITY_HEADER_KEY_REPORT_ONLY;
- }
-
- return self::SECURITY_HEADER_KEY;
- }
-
- public function getDirectives(): array
- {
- return $this->directives;
- }
-
- /**
- * @throws InvalidDirectiveException
- */
- public function addDirective(string $directive, $values): self
- {
- if (! Directive::isValidDirective($directive)) {
- throw new InvalidDirectiveException($directive);
- }
- $this->directives[$directive] = array_map(function ($value) use ($directive) {
- return $this->sanitizeValue($value);
- }, $values);
-
- return $this;
- }
-
- public function getNonce(): Nonce
- {
- return $this->nonce;
- }
-
- public function hasNonceDirectiveValue(): bool
- {
- return $this->hasNonceDirectiveValue;
- }
-
- public function __toString(): string
- {
- $directives = $this->getDirectives();
- $keys = array_keys($directives);
-
- $items = array_map(function ($values, $directive) {
- $value = implode(' ', $values);
-
- return "$directive $value";
- }, $directives, $keys);
-
- return implode(';', $items).';';
- }
-
- private function sanitizeValue(string $value): string
- {
- if ($this->isSpecialValue($value)) {
- return "'$value'";
- }
-
- if ($value === '{nonce}') {
- $this->hasNonceDirectiveValue = true;
-
- return "'nonce-".$this->getNonce()->getValue()."'";
- }
-
- return $value;
- }
-
- private function isSpecialValue(string $directive): bool
- {
- return in_array($directive, self::SPECIAL_DIRECTIVES);
- }
-}
diff --git a/Flowpack.ContentSecurityPolicy/Configuration/Settings.yaml b/Flowpack.ContentSecurityPolicy/Configuration/Settings.yaml
deleted file mode 100644
index bd83845..0000000
--- a/Flowpack.ContentSecurityPolicy/Configuration/Settings.yaml
+++ /dev/null
@@ -1,80 +0,0 @@
-Flowpack:
- ContentSecurityPolicy:
- enabled: true
- report-only: false
- content-security-policy:
- default:
- base-uri:
- - 'self'
- connect-src:
- - 'self'
- default-src:
- - 'self'
- form-action:
- - 'self'
- img-src:
- - 'self'
- media-src:
- - 'self'
- frame-src:
- - 'self'
- object-src:
- - 'self'
- script-src:
- - 'self'
- style-src:
- - 'self'
- style-src-attr:
- - 'self'
- style-src-elem:
- - 'self'
- font-src:
- - 'self'
- custom: [ ]
- backend:
- base-uri:
- - 'self'
- connect-src:
- - 'self'
- default-src:
- - 'self'
- form-action:
- - 'self'
- img-src:
- - 'self'
- - 'data:'
- media-src:
- - 'self'
- frame-src:
- - 'self'
- object-src:
- - 'self'
- script-src:
- - 'self'
- - 'unsafe-inline'
- - 'unsafe-eval'
- style-src:
- - 'self'
- - 'unsafe-inline'
- style-src-attr:
- - 'self'
- - 'unsafe-inline'
- style-src-elem:
- - 'self'
- - 'unsafe-inline'
- font-src:
- - 'self'
- - 'data:'
- custom-backend: [ ]
-
-Neos:
- Neos:
- fusion:
- autoInclude:
- Flowpack.ContentSecurityPolicy: true
- Flow:
- http:
- middlewares:
- 'cspHeader':
- position: 'after routing'
- middleware: 'Flowpack\ContentSecurityPolicy\Http\CspHeaderMiddleware'
diff --git a/Flowpack.ContentSecurityPolicy/LICENSE b/Flowpack.ContentSecurityPolicy/LICENSE
deleted file mode 100644
index c15a994..0000000
--- a/Flowpack.ContentSecurityPolicy/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2018-2024 Lars Nieuwenhuizen, Sandstorm Media GmbH
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/Flowpack.ContentSecurityPolicy/README.md b/Flowpack.ContentSecurityPolicy/README.md
deleted file mode 100644
index 77f899d..0000000
--- a/Flowpack.ContentSecurityPolicy/README.md
+++ /dev/null
@@ -1,174 +0,0 @@
-# Flowpack.ContentSecurityPolicy
-
-
-* [Flowpack.ContentSecurityPolicy](#flowpackcontentsecuritypolicy)
- * [Introduction](#introduction)
- * [Usage](#usage)
- * [Custom directives and values](#custom-directives-and-values)
- * [Show CSP configuration](#show-csp-configuration)
- * [Disable or report only](#disable-or-report-only)
- * [Nonce](#nonce)
- * [Backend](#backend)
- * [Thank you](#thank-you)
-
-
-## Introduction
-
-Flow/Neos package to set your site's content security policy header easily with yaml.
-
-## Usage
-
-Import the package using composer:
-
-```bash
-composer require flowpack/content-security-policy
-```
-
-The package is automatically active once imported.
-By default, the response header `Content-Security-Policy` will now be included.
-
-It will use the default configuration which looks like this:
-
-```yaml
-Flowpack:
- ContentSecurityPolicy:
- enabled: true
- report-only: false
- content-security-policy:
- default:
- base-uri:
- - 'self'
- connect-src:
- - 'self'
- default-src:
- - 'self'
- form-action:
- - 'self'
- img-src:
- - 'self'
- media-src:
- - 'self'
- frame-src:
- - 'self'
- object-src:
- - 'self'
- script-src:
- - 'self'
- style-src:
- - 'self'
- style-src-attr:
- - 'self'
- style-src-elem:
- - 'self'
- font-src:
- - 'self'
- custom: [ ]
-```
-
-Now only resources from the same origin are allowed for the most common directives.
-It is enabled by default and the report-only mode is disabled.
-
-## Custom directives and values
-
-The default configuration will probably not suit your needs so you can add your own configuration by adding the array
-custom like this in your own yaml configuration files:
-
-```yaml
-Flowpack:
- ContentSecurityPolicy:
- content-security-policy:
- custom:
- frame-src:
- - 'https://www.youtube.com'
- - 'https://staticxx.facebook.com'
-```
-
-If you fully want to override the entire default config then just override the default key in yaml.
-
-### Show CSP configuration
-
-To show the parsed configuration, the built-in command `./flow cspconfig:show` can be used.
-It shows all directives used by the frontend and the backend.
-
-## Disable or report only
-
-To disable the header simply set `enabled` to false.
-If you want to add it as a report only header set `report-only` to true.
-That way you have the option to see the possible errors without breaking functionality.
-
-## Nonce
-
-You might want to use a nonce to allow inline scripts and styles to be still secure.
-To do this simply add `{nonce}` as an option in a directive. Like this:
-
-```yaml
-Flowpack:
- ContentSecurityPolicy:
- content-security-policy:
- custom:
- script-src:
- - '{nonce}'
-```
-
-Now the header will include a `nonce-automatedgeneratedrandomstring` in the script-src directive.
-So inline scripts without the corresponding nonce will be blocked.
-
-The nonce will be automatically added to all your script/style tags.
-
-## Backend
-
-Due to the current nature of the Neos backend being rendered a bit different then the frontend a separate policy is
-added for the backend.
-I currently have found no suitable way the add the nonce in the inline scripts in the Neos UI package.
-So the CSP for the backend looks like this:
-
-```yaml
-Flowpack:
- ContentSecurityPolicy:
- content-security-policy:
- backend:
- base-uri:
- - 'self'
- connect-src:
- - 'self'
- default-src:
- - 'self'
- form-action:
- - 'self'
- img-src:
- - 'self'
- - 'data:'
- media-src:
- - 'self'
- frame-src:
- - 'self'
- object-src:
- - 'self'
- script-src:
- - 'self'
- - 'unsafe-inline'
- - 'unsafe-eval'
- style-src:
- - 'self'
- - 'unsafe-inline'
- style-src-attr:
- - 'self'
- - 'unsafe-inline'
- style-src-elem:
- - 'self'
- - 'unsafe-inline'
- font-src:
- - 'self'
- - 'data:'
- custom-backend: [ ]
-```
-
-Unsafe inline scripts and styles are allowed in the backend because otherwise the backend won't work.
-
-Again you can add your own policies in the custom-backend array the same way as the custom array for the frontend.
-
-## Thank you
-
-This package originates from https://github.com/LarsNieuwenhuizen/Nieuwenhuizen.ContentSecurityPolicy.
-
-Thank you Lars Nieuwenhuizen for your work.
diff --git a/Flowpack.ContentSecurityPolicy/composer.json b/Flowpack.ContentSecurityPolicy/composer.json
deleted file mode 100644
index d06837b..0000000
--- a/Flowpack.ContentSecurityPolicy/composer.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "description": "Configure your content-security-policy header easily with yaml.",
- "type": "neos-package",
- "name": "flowpack/content-security-policy",
- "license": [
- "MIT"
- ],
- "require": {
- "php": "^8.1",
- "neos/flow": "^8.3"
- },
- "autoload": {
- "psr-4": {
- "Flowpack\\ContentSecurityPolicy\\": "Classes/"
- }
- },
- "extra": {
- "neos": {
- "package-key": "Flowpack.ContentSecurityPolicy"
- }
- },
- "config": {
- "allow-plugins": {
- "neos/composer-plugin": true
- }
- }
-}