瀏覽代碼

Add a way to modify CSP rules within an extension (#6246)

This will allow to change CSP rules to authorize the use of external scripts.
We might need to add some safeguard since it will be virtually possible to
load any script even malicious one.
Alexis Degrugillier 2 年之前
父節點
當前提交
7da0e70a72
共有 3 個文件被更改,包括 32 次插入0 次删除
  1. 13 0
      docs/en/developers/03_Backend/05_Extensions.md
  2. 3 0
      lib/Minz/ActionController.php
  3. 16 0
      lib/Minz/Extension.php

+ 13 - 0
docs/en/developers/03_Backend/05_Extensions.md

@@ -164,6 +164,19 @@ The following events are available:
 * `post_update` (`function(none) -> none`): **TODO** add documentation.
 * `simplepie_before_init` (`function($simplePie, $feed) -> none`): **TODO** add documentation.
 
+### Injecting CDN content
+
+When using the `init` method, it is possible to inject scripts from CDN using the `Minz_View::appendScript` directive.
+FreshRSS will include the script in the page but will not load it since it will be blocked by the default content security policy (**CSP**).
+To amend the existing CSP, you need to define the extension CSP policies:
+```php
+// in the extension.php file
+protected array $csp_policies = [
+	'default-src' => 'example.org',
+];
+```
+This will only amend the extension CSP to FreshRSS CSP.
+
 ### Writing your own configure.phtml
 
 When you want to support user configurations for your extension or simply display some information, you have to create the `configure.phtml` file.

+ 3 - 0
lib/Minz/ActionController.php

@@ -99,6 +99,9 @@ abstract class Minz_ActionController {
 	 */
 	public function declareCspHeader(): void {
 		$policies = [];
+		foreach (Minz_ExtensionManager::listExtensions(true) as $extension) {
+			$extension->amendCsp($this->csp_policies);
+		}
 		foreach ($this->csp_policies as $directive => $sources) {
 			$policies[] = $directive . ' ' . $sources;
 		}

+ 16 - 0
lib/Minz/Extension.php

@@ -26,6 +26,9 @@ abstract class Minz_Extension {
 
 	private bool $is_enabled;
 
+	/** @var string[] */
+	protected array $csp_policies = [];
+
 	/**
 	 * The constructor to assign specific information to the extension.
 	 *
@@ -390,4 +393,17 @@ abstract class Minz_Extension {
 			unlink($path);
 		}
 	}
+
+	/**
+	 * @param string[] $policies
+	 */
+	public function amendCsp(array &$policies): void {
+		foreach ($this->csp_policies as $policy => $source) {
+			if (array_key_exists($policy, $policies)) {
+				$policies[$policy] .= ' ' . $source;
+			} else {
+				$policies[$policy] = $source;
+			}
+		}
+	}
 }