Passed
Push — master ( 884c80...66013f )
by Roeland
21:51 queued 10:39
created
lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php 1 patch
Indentation   +492 added lines, -492 removed lines patch added patch discarded remove patch
@@ -38,496 +38,496 @@
 block discarded – undo
38 38
  * @since 9.0.0
39 39
  */
40 40
 class EmptyContentSecurityPolicy {
41
-	/** @var bool Whether inline JS snippets are allowed */
42
-	protected $inlineScriptAllowed = null;
43
-	/** @var string Whether JS nonces should be used */
44
-	protected $useJsNonce = null;
45
-	/**
46
-	 * @var bool Whether eval in JS scripts is allowed
47
-	 * TODO: Disallow per default
48
-	 * @link https://github.com/owncloud/core/issues/11925
49
-	 */
50
-	protected $evalScriptAllowed = null;
51
-	/** @var array Domains from which scripts can get loaded */
52
-	protected $allowedScriptDomains = null;
53
-	/**
54
-	 * @var bool Whether inline CSS is allowed
55
-	 * TODO: Disallow per default
56
-	 * @link https://github.com/owncloud/core/issues/13458
57
-	 */
58
-	protected $inlineStyleAllowed = null;
59
-	/** @var array Domains from which CSS can get loaded */
60
-	protected $allowedStyleDomains = null;
61
-	/** @var array Domains from which images can get loaded */
62
-	protected $allowedImageDomains = null;
63
-	/** @var array Domains to which connections can be done */
64
-	protected $allowedConnectDomains = null;
65
-	/** @var array Domains from which media elements can be loaded */
66
-	protected $allowedMediaDomains = null;
67
-	/** @var array Domains from which object elements can be loaded */
68
-	protected $allowedObjectDomains = null;
69
-	/** @var array Domains from which iframes can be loaded */
70
-	protected $allowedFrameDomains = null;
71
-	/** @var array Domains from which fonts can be loaded */
72
-	protected $allowedFontDomains = null;
73
-	/** @var array Domains from which web-workers and nested browsing content can load elements */
74
-	protected $allowedChildSrcDomains = null;
75
-	/** @var array Domains which can embed this Nextcloud instance */
76
-	protected $allowedFrameAncestors = null;
77
-	/** @var array Domains from which web-workers can be loaded */
78
-	protected $allowedWorkerSrcDomains = null;
79
-	/** @var array Domains which can be used as target for forms */
80
-	protected $allowedFormActionDomains = null;
81
-
82
-	/** @var array Locations to report violations to */
83
-	protected $reportTo = null;
84
-
85
-	/**
86
-	 * Whether inline JavaScript snippets are allowed or forbidden
87
-	 * @param bool $state
88
-	 * @return $this
89
-	 * @since 8.1.0
90
-	 * @deprecated 10.0 CSP tokens are now used
91
-	 */
92
-	public function allowInlineScript($state = false) {
93
-		$this->inlineScriptAllowed = $state;
94
-		return $this;
95
-	}
96
-
97
-	/**
98
-	 * Use the according JS nonce
99
-	 * This method is only for CSPMiddleware, custom values are ignored in mergePolicies of ContentSecurityPolicyManager
100
-	 *
101
-	 * @param string $nonce
102
-	 * @return $this
103
-	 * @since 11.0.0
104
-	 */
105
-	public function useJsNonce($nonce) {
106
-		$this->useJsNonce = $nonce;
107
-		return $this;
108
-	}
109
-
110
-	/**
111
-	 * Whether eval in JavaScript is allowed or forbidden
112
-	 * @param bool $state
113
-	 * @return $this
114
-	 * @since 8.1.0
115
-	 * @deprecated Eval should not be used anymore. Please update your scripts. This function will stop functioning in a future version of Nextcloud.
116
-	 */
117
-	public function allowEvalScript($state = true) {
118
-		$this->evalScriptAllowed = $state;
119
-		return $this;
120
-	}
121
-
122
-	/**
123
-	 * Allows to execute JavaScript files from a specific domain. Use * to
124
-	 * allow JavaScript from all domains.
125
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
126
-	 * @return $this
127
-	 * @since 8.1.0
128
-	 */
129
-	public function addAllowedScriptDomain($domain) {
130
-		$this->allowedScriptDomains[] = $domain;
131
-		return $this;
132
-	}
133
-
134
-	/**
135
-	 * Remove the specified allowed script domain from the allowed domains.
136
-	 *
137
-	 * @param string $domain
138
-	 * @return $this
139
-	 * @since 8.1.0
140
-	 */
141
-	public function disallowScriptDomain($domain) {
142
-		$this->allowedScriptDomains = array_diff($this->allowedScriptDomains, [$domain]);
143
-		return $this;
144
-	}
145
-
146
-	/**
147
-	 * Whether inline CSS snippets are allowed or forbidden
148
-	 * @param bool $state
149
-	 * @return $this
150
-	 * @since 8.1.0
151
-	 */
152
-	public function allowInlineStyle($state = true) {
153
-		$this->inlineStyleAllowed = $state;
154
-		return $this;
155
-	}
156
-
157
-	/**
158
-	 * Allows to execute CSS files from a specific domain. Use * to allow
159
-	 * CSS from all domains.
160
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
161
-	 * @return $this
162
-	 * @since 8.1.0
163
-	 */
164
-	public function addAllowedStyleDomain($domain) {
165
-		$this->allowedStyleDomains[] = $domain;
166
-		return $this;
167
-	}
168
-
169
-	/**
170
-	 * Remove the specified allowed style domain from the allowed domains.
171
-	 *
172
-	 * @param string $domain
173
-	 * @return $this
174
-	 * @since 8.1.0
175
-	 */
176
-	public function disallowStyleDomain($domain) {
177
-		$this->allowedStyleDomains = array_diff($this->allowedStyleDomains, [$domain]);
178
-		return $this;
179
-	}
180
-
181
-	/**
182
-	 * Allows using fonts from a specific domain. Use * to allow
183
-	 * fonts from all domains.
184
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
185
-	 * @return $this
186
-	 * @since 8.1.0
187
-	 */
188
-	public function addAllowedFontDomain($domain) {
189
-		$this->allowedFontDomains[] = $domain;
190
-		return $this;
191
-	}
192
-
193
-	/**
194
-	 * Remove the specified allowed font domain from the allowed domains.
195
-	 *
196
-	 * @param string $domain
197
-	 * @return $this
198
-	 * @since 8.1.0
199
-	 */
200
-	public function disallowFontDomain($domain) {
201
-		$this->allowedFontDomains = array_diff($this->allowedFontDomains, [$domain]);
202
-		return $this;
203
-	}
204
-
205
-	/**
206
-	 * Allows embedding images from a specific domain. Use * to allow
207
-	 * images from all domains.
208
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
209
-	 * @return $this
210
-	 * @since 8.1.0
211
-	 */
212
-	public function addAllowedImageDomain($domain) {
213
-		$this->allowedImageDomains[] = $domain;
214
-		return $this;
215
-	}
216
-
217
-	/**
218
-	 * Remove the specified allowed image domain from the allowed domains.
219
-	 *
220
-	 * @param string $domain
221
-	 * @return $this
222
-	 * @since 8.1.0
223
-	 */
224
-	public function disallowImageDomain($domain) {
225
-		$this->allowedImageDomains = array_diff($this->allowedImageDomains, [$domain]);
226
-		return $this;
227
-	}
228
-
229
-	/**
230
-	 * To which remote domains the JS connect to.
231
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
232
-	 * @return $this
233
-	 * @since 8.1.0
234
-	 */
235
-	public function addAllowedConnectDomain($domain) {
236
-		$this->allowedConnectDomains[] = $domain;
237
-		return $this;
238
-	}
239
-
240
-	/**
241
-	 * Remove the specified allowed connect domain from the allowed domains.
242
-	 *
243
-	 * @param string $domain
244
-	 * @return $this
245
-	 * @since 8.1.0
246
-	 */
247
-	public function disallowConnectDomain($domain) {
248
-		$this->allowedConnectDomains = array_diff($this->allowedConnectDomains, [$domain]);
249
-		return $this;
250
-	}
251
-
252
-	/**
253
-	 * From which domains media elements can be embedded.
254
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
255
-	 * @return $this
256
-	 * @since 8.1.0
257
-	 */
258
-	public function addAllowedMediaDomain($domain) {
259
-		$this->allowedMediaDomains[] = $domain;
260
-		return $this;
261
-	}
262
-
263
-	/**
264
-	 * Remove the specified allowed media domain from the allowed domains.
265
-	 *
266
-	 * @param string $domain
267
-	 * @return $this
268
-	 * @since 8.1.0
269
-	 */
270
-	public function disallowMediaDomain($domain) {
271
-		$this->allowedMediaDomains = array_diff($this->allowedMediaDomains, [$domain]);
272
-		return $this;
273
-	}
274
-
275
-	/**
276
-	 * From which domains objects such as <object>, <embed> or <applet> are executed
277
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
278
-	 * @return $this
279
-	 * @since 8.1.0
280
-	 */
281
-	public function addAllowedObjectDomain($domain) {
282
-		$this->allowedObjectDomains[] = $domain;
283
-		return $this;
284
-	}
285
-
286
-	/**
287
-	 * Remove the specified allowed object domain from the allowed domains.
288
-	 *
289
-	 * @param string $domain
290
-	 * @return $this
291
-	 * @since 8.1.0
292
-	 */
293
-	public function disallowObjectDomain($domain) {
294
-		$this->allowedObjectDomains = array_diff($this->allowedObjectDomains, [$domain]);
295
-		return $this;
296
-	}
297
-
298
-	/**
299
-	 * Which domains can be embedded in an iframe
300
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
301
-	 * @return $this
302
-	 * @since 8.1.0
303
-	 */
304
-	public function addAllowedFrameDomain($domain) {
305
-		$this->allowedFrameDomains[] = $domain;
306
-		return $this;
307
-	}
308
-
309
-	/**
310
-	 * Remove the specified allowed frame domain from the allowed domains.
311
-	 *
312
-	 * @param string $domain
313
-	 * @return $this
314
-	 * @since 8.1.0
315
-	 */
316
-	public function disallowFrameDomain($domain) {
317
-		$this->allowedFrameDomains = array_diff($this->allowedFrameDomains, [$domain]);
318
-		return $this;
319
-	}
320
-
321
-	/**
322
-	 * Domains from which web-workers and nested browsing content can load elements
323
-	 * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
324
-	 * @return $this
325
-	 * @since 8.1.0
326
-	 * @deprecated 15.0.0 use addAllowedWorkerSrcDomains or addAllowedFrameDomain
327
-	 */
328
-	public function addAllowedChildSrcDomain($domain) {
329
-		$this->allowedChildSrcDomains[] = $domain;
330
-		return $this;
331
-	}
332
-
333
-	/**
334
-	 * Remove the specified allowed child src domain from the allowed domains.
335
-	 *
336
-	 * @param string $domain
337
-	 * @return $this
338
-	 * @since 8.1.0
339
-	 * @deprecated 15.0.0 use the WorkerSrcDomains or FrameDomain
340
-	 */
341
-	public function disallowChildSrcDomain($domain) {
342
-		$this->allowedChildSrcDomains = array_diff($this->allowedChildSrcDomains, [$domain]);
343
-		return $this;
344
-	}
345
-
346
-	/**
347
-	 * Domains which can embed an iFrame of the Nextcloud instance
348
-	 *
349
-	 * @param string $domain
350
-	 * @return $this
351
-	 * @since 13.0.0
352
-	 */
353
-	public function addAllowedFrameAncestorDomain($domain) {
354
-		$this->allowedFrameAncestors[] = $domain;
355
-		return $this;
356
-	}
357
-
358
-	/**
359
-	 * Domains which can embed an iFrame of the Nextcloud instance
360
-	 *
361
-	 * @param string $domain
362
-	 * @return $this
363
-	 * @since 13.0.0
364
-	 */
365
-	public function disallowFrameAncestorDomain($domain) {
366
-		$this->allowedFrameAncestors = array_diff($this->allowedFrameAncestors, [$domain]);
367
-		return $this;
368
-	}
369
-
370
-	/**
371
-	 * Domain from which workers can be loaded
372
-	 *
373
-	 * @param string $domain
374
-	 * @return $this
375
-	 * @since 15.0.0
376
-	 */
377
-	public function addAllowedWorkerSrcDomain(string $domain) {
378
-		$this->allowedWorkerSrcDomains[] = $domain;
379
-		return $this;
380
-	}
381
-
382
-	/**
383
-	 * Remove domain from which workers can be loaded
384
-	 *
385
-	 * @param string $domain
386
-	 * @return $this
387
-	 * @since 15.0.0
388
-	 */
389
-	public function disallowWorkerSrcDomain(string $domain) {
390
-		$this->allowedWorkerSrcDomains = array_diff($this->allowedWorkerSrcDomains, [$domain]);
391
-		return $this;
392
-	}
393
-
394
-	/**
395
-	 * Domain to where forms can submit
396
-	 *
397
-	 * @since 17.0.0
398
-	 *
399
-	 * @return $this
400
-	 */
401
-	public function addAllowedFormActionDomain(string $domain) {
402
-		$this->allowedFormActionDomains[] = $domain;
403
-		return $this;
404
-	}
405
-
406
-	/**
407
-	 * Remove domain to where forms can submit
408
-	 *
409
-	 * @return $this
410
-	 * @since 17.0.0
411
-	 */
412
-	public function disallowFormActionDomain(string $domain) {
413
-		$this->allowedFormActionDomains = array_diff($this->allowedFormActionDomains, [$domain]);
414
-		return $this;
415
-	}
416
-
417
-	/**
418
-	 * Add location to report CSP violations to
419
-	 *
420
-	 * @param string $location
421
-	 * @return $this
422
-	 * @since 15.0.0
423
-	 */
424
-	public function addReportTo(string $location) {
425
-		$this->reportTo[] = $location;
426
-		return $this;
427
-	}
428
-
429
-	/**
430
-	 * Get the generated Content-Security-Policy as a string
431
-	 * @return string
432
-	 * @since 8.1.0
433
-	 */
434
-	public function buildPolicy() {
435
-		$policy = "default-src 'none';";
436
-		$policy .= "base-uri 'none';";
437
-		$policy .= "manifest-src 'self';";
438
-
439
-		if (!empty($this->allowedScriptDomains) || $this->inlineScriptAllowed || $this->evalScriptAllowed) {
440
-			$policy .= 'script-src ';
441
-			if (is_string($this->useJsNonce)) {
442
-				$policy .= '\'nonce-'.base64_encode($this->useJsNonce).'\'';
443
-				$allowedScriptDomains = array_flip($this->allowedScriptDomains);
444
-				unset($allowedScriptDomains['\'self\'']);
445
-				$this->allowedScriptDomains = array_flip($allowedScriptDomains);
446
-				if (count($allowedScriptDomains) !== 0) {
447
-					$policy .= ' ';
448
-				}
449
-			}
450
-			if (is_array($this->allowedScriptDomains)) {
451
-				$policy .= implode(' ', $this->allowedScriptDomains);
452
-			}
453
-			if ($this->inlineScriptAllowed) {
454
-				$policy .= ' \'unsafe-inline\'';
455
-			}
456
-			if ($this->evalScriptAllowed) {
457
-				$policy .= ' \'unsafe-eval\'';
458
-			}
459
-			$policy .= ';';
460
-		}
461
-
462
-		if (!empty($this->allowedStyleDomains) || $this->inlineStyleAllowed) {
463
-			$policy .= 'style-src ';
464
-			if (is_array($this->allowedStyleDomains)) {
465
-				$policy .= implode(' ', $this->allowedStyleDomains);
466
-			}
467
-			if ($this->inlineStyleAllowed) {
468
-				$policy .= ' \'unsafe-inline\'';
469
-			}
470
-			$policy .= ';';
471
-		}
472
-
473
-		if (!empty($this->allowedImageDomains)) {
474
-			$policy .= 'img-src ' . implode(' ', $this->allowedImageDomains);
475
-			$policy .= ';';
476
-		}
477
-
478
-		if (!empty($this->allowedFontDomains)) {
479
-			$policy .= 'font-src ' . implode(' ', $this->allowedFontDomains);
480
-			$policy .= ';';
481
-		}
482
-
483
-		if (!empty($this->allowedConnectDomains)) {
484
-			$policy .= 'connect-src ' . implode(' ', $this->allowedConnectDomains);
485
-			$policy .= ';';
486
-		}
487
-
488
-		if (!empty($this->allowedMediaDomains)) {
489
-			$policy .= 'media-src ' . implode(' ', $this->allowedMediaDomains);
490
-			$policy .= ';';
491
-		}
492
-
493
-		if (!empty($this->allowedObjectDomains)) {
494
-			$policy .= 'object-src ' . implode(' ', $this->allowedObjectDomains);
495
-			$policy .= ';';
496
-		}
497
-
498
-		if (!empty($this->allowedFrameDomains)) {
499
-			$policy .= 'frame-src ';
500
-			$policy .= implode(' ', $this->allowedFrameDomains);
501
-			$policy .= ';';
502
-		}
503
-
504
-		if (!empty($this->allowedChildSrcDomains)) {
505
-			$policy .= 'child-src ' . implode(' ', $this->allowedChildSrcDomains);
506
-			$policy .= ';';
507
-		}
508
-
509
-		if (!empty($this->allowedFrameAncestors)) {
510
-			$policy .= 'frame-ancestors ' . implode(' ', $this->allowedFrameAncestors);
511
-			$policy .= ';';
512
-		} else {
513
-			$policy .= 'frame-ancestors \'none\';';
514
-		}
515
-
516
-		if (!empty($this->allowedWorkerSrcDomains)) {
517
-			$policy .= 'worker-src ' . implode(' ', $this->allowedWorkerSrcDomains);
518
-			$policy .= ';';
519
-		}
520
-
521
-		if (!empty($this->allowedFormActionDomains)) {
522
-			$policy .= 'form-action ' . implode(' ', $this->allowedFormActionDomains);
523
-			$policy .= ';';
524
-		}
525
-
526
-		if (!empty($this->reportTo)) {
527
-			$policy .= 'report-uri ' . implode(' ', $this->reportTo);
528
-			$policy .= ';';
529
-		}
530
-
531
-		return rtrim($policy, ';');
532
-	}
41
+    /** @var bool Whether inline JS snippets are allowed */
42
+    protected $inlineScriptAllowed = null;
43
+    /** @var string Whether JS nonces should be used */
44
+    protected $useJsNonce = null;
45
+    /**
46
+     * @var bool Whether eval in JS scripts is allowed
47
+     * TODO: Disallow per default
48
+     * @link https://github.com/owncloud/core/issues/11925
49
+     */
50
+    protected $evalScriptAllowed = null;
51
+    /** @var array Domains from which scripts can get loaded */
52
+    protected $allowedScriptDomains = null;
53
+    /**
54
+     * @var bool Whether inline CSS is allowed
55
+     * TODO: Disallow per default
56
+     * @link https://github.com/owncloud/core/issues/13458
57
+     */
58
+    protected $inlineStyleAllowed = null;
59
+    /** @var array Domains from which CSS can get loaded */
60
+    protected $allowedStyleDomains = null;
61
+    /** @var array Domains from which images can get loaded */
62
+    protected $allowedImageDomains = null;
63
+    /** @var array Domains to which connections can be done */
64
+    protected $allowedConnectDomains = null;
65
+    /** @var array Domains from which media elements can be loaded */
66
+    protected $allowedMediaDomains = null;
67
+    /** @var array Domains from which object elements can be loaded */
68
+    protected $allowedObjectDomains = null;
69
+    /** @var array Domains from which iframes can be loaded */
70
+    protected $allowedFrameDomains = null;
71
+    /** @var array Domains from which fonts can be loaded */
72
+    protected $allowedFontDomains = null;
73
+    /** @var array Domains from which web-workers and nested browsing content can load elements */
74
+    protected $allowedChildSrcDomains = null;
75
+    /** @var array Domains which can embed this Nextcloud instance */
76
+    protected $allowedFrameAncestors = null;
77
+    /** @var array Domains from which web-workers can be loaded */
78
+    protected $allowedWorkerSrcDomains = null;
79
+    /** @var array Domains which can be used as target for forms */
80
+    protected $allowedFormActionDomains = null;
81
+
82
+    /** @var array Locations to report violations to */
83
+    protected $reportTo = null;
84
+
85
+    /**
86
+     * Whether inline JavaScript snippets are allowed or forbidden
87
+     * @param bool $state
88
+     * @return $this
89
+     * @since 8.1.0
90
+     * @deprecated 10.0 CSP tokens are now used
91
+     */
92
+    public function allowInlineScript($state = false) {
93
+        $this->inlineScriptAllowed = $state;
94
+        return $this;
95
+    }
96
+
97
+    /**
98
+     * Use the according JS nonce
99
+     * This method is only for CSPMiddleware, custom values are ignored in mergePolicies of ContentSecurityPolicyManager
100
+     *
101
+     * @param string $nonce
102
+     * @return $this
103
+     * @since 11.0.0
104
+     */
105
+    public function useJsNonce($nonce) {
106
+        $this->useJsNonce = $nonce;
107
+        return $this;
108
+    }
109
+
110
+    /**
111
+     * Whether eval in JavaScript is allowed or forbidden
112
+     * @param bool $state
113
+     * @return $this
114
+     * @since 8.1.0
115
+     * @deprecated Eval should not be used anymore. Please update your scripts. This function will stop functioning in a future version of Nextcloud.
116
+     */
117
+    public function allowEvalScript($state = true) {
118
+        $this->evalScriptAllowed = $state;
119
+        return $this;
120
+    }
121
+
122
+    /**
123
+     * Allows to execute JavaScript files from a specific domain. Use * to
124
+     * allow JavaScript from all domains.
125
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
126
+     * @return $this
127
+     * @since 8.1.0
128
+     */
129
+    public function addAllowedScriptDomain($domain) {
130
+        $this->allowedScriptDomains[] = $domain;
131
+        return $this;
132
+    }
133
+
134
+    /**
135
+     * Remove the specified allowed script domain from the allowed domains.
136
+     *
137
+     * @param string $domain
138
+     * @return $this
139
+     * @since 8.1.0
140
+     */
141
+    public function disallowScriptDomain($domain) {
142
+        $this->allowedScriptDomains = array_diff($this->allowedScriptDomains, [$domain]);
143
+        return $this;
144
+    }
145
+
146
+    /**
147
+     * Whether inline CSS snippets are allowed or forbidden
148
+     * @param bool $state
149
+     * @return $this
150
+     * @since 8.1.0
151
+     */
152
+    public function allowInlineStyle($state = true) {
153
+        $this->inlineStyleAllowed = $state;
154
+        return $this;
155
+    }
156
+
157
+    /**
158
+     * Allows to execute CSS files from a specific domain. Use * to allow
159
+     * CSS from all domains.
160
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
161
+     * @return $this
162
+     * @since 8.1.0
163
+     */
164
+    public function addAllowedStyleDomain($domain) {
165
+        $this->allowedStyleDomains[] = $domain;
166
+        return $this;
167
+    }
168
+
169
+    /**
170
+     * Remove the specified allowed style domain from the allowed domains.
171
+     *
172
+     * @param string $domain
173
+     * @return $this
174
+     * @since 8.1.0
175
+     */
176
+    public function disallowStyleDomain($domain) {
177
+        $this->allowedStyleDomains = array_diff($this->allowedStyleDomains, [$domain]);
178
+        return $this;
179
+    }
180
+
181
+    /**
182
+     * Allows using fonts from a specific domain. Use * to allow
183
+     * fonts from all domains.
184
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
185
+     * @return $this
186
+     * @since 8.1.0
187
+     */
188
+    public function addAllowedFontDomain($domain) {
189
+        $this->allowedFontDomains[] = $domain;
190
+        return $this;
191
+    }
192
+
193
+    /**
194
+     * Remove the specified allowed font domain from the allowed domains.
195
+     *
196
+     * @param string $domain
197
+     * @return $this
198
+     * @since 8.1.0
199
+     */
200
+    public function disallowFontDomain($domain) {
201
+        $this->allowedFontDomains = array_diff($this->allowedFontDomains, [$domain]);
202
+        return $this;
203
+    }
204
+
205
+    /**
206
+     * Allows embedding images from a specific domain. Use * to allow
207
+     * images from all domains.
208
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
209
+     * @return $this
210
+     * @since 8.1.0
211
+     */
212
+    public function addAllowedImageDomain($domain) {
213
+        $this->allowedImageDomains[] = $domain;
214
+        return $this;
215
+    }
216
+
217
+    /**
218
+     * Remove the specified allowed image domain from the allowed domains.
219
+     *
220
+     * @param string $domain
221
+     * @return $this
222
+     * @since 8.1.0
223
+     */
224
+    public function disallowImageDomain($domain) {
225
+        $this->allowedImageDomains = array_diff($this->allowedImageDomains, [$domain]);
226
+        return $this;
227
+    }
228
+
229
+    /**
230
+     * To which remote domains the JS connect to.
231
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
232
+     * @return $this
233
+     * @since 8.1.0
234
+     */
235
+    public function addAllowedConnectDomain($domain) {
236
+        $this->allowedConnectDomains[] = $domain;
237
+        return $this;
238
+    }
239
+
240
+    /**
241
+     * Remove the specified allowed connect domain from the allowed domains.
242
+     *
243
+     * @param string $domain
244
+     * @return $this
245
+     * @since 8.1.0
246
+     */
247
+    public function disallowConnectDomain($domain) {
248
+        $this->allowedConnectDomains = array_diff($this->allowedConnectDomains, [$domain]);
249
+        return $this;
250
+    }
251
+
252
+    /**
253
+     * From which domains media elements can be embedded.
254
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
255
+     * @return $this
256
+     * @since 8.1.0
257
+     */
258
+    public function addAllowedMediaDomain($domain) {
259
+        $this->allowedMediaDomains[] = $domain;
260
+        return $this;
261
+    }
262
+
263
+    /**
264
+     * Remove the specified allowed media domain from the allowed domains.
265
+     *
266
+     * @param string $domain
267
+     * @return $this
268
+     * @since 8.1.0
269
+     */
270
+    public function disallowMediaDomain($domain) {
271
+        $this->allowedMediaDomains = array_diff($this->allowedMediaDomains, [$domain]);
272
+        return $this;
273
+    }
274
+
275
+    /**
276
+     * From which domains objects such as <object>, <embed> or <applet> are executed
277
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
278
+     * @return $this
279
+     * @since 8.1.0
280
+     */
281
+    public function addAllowedObjectDomain($domain) {
282
+        $this->allowedObjectDomains[] = $domain;
283
+        return $this;
284
+    }
285
+
286
+    /**
287
+     * Remove the specified allowed object domain from the allowed domains.
288
+     *
289
+     * @param string $domain
290
+     * @return $this
291
+     * @since 8.1.0
292
+     */
293
+    public function disallowObjectDomain($domain) {
294
+        $this->allowedObjectDomains = array_diff($this->allowedObjectDomains, [$domain]);
295
+        return $this;
296
+    }
297
+
298
+    /**
299
+     * Which domains can be embedded in an iframe
300
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
301
+     * @return $this
302
+     * @since 8.1.0
303
+     */
304
+    public function addAllowedFrameDomain($domain) {
305
+        $this->allowedFrameDomains[] = $domain;
306
+        return $this;
307
+    }
308
+
309
+    /**
310
+     * Remove the specified allowed frame domain from the allowed domains.
311
+     *
312
+     * @param string $domain
313
+     * @return $this
314
+     * @since 8.1.0
315
+     */
316
+    public function disallowFrameDomain($domain) {
317
+        $this->allowedFrameDomains = array_diff($this->allowedFrameDomains, [$domain]);
318
+        return $this;
319
+    }
320
+
321
+    /**
322
+     * Domains from which web-workers and nested browsing content can load elements
323
+     * @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
324
+     * @return $this
325
+     * @since 8.1.0
326
+     * @deprecated 15.0.0 use addAllowedWorkerSrcDomains or addAllowedFrameDomain
327
+     */
328
+    public function addAllowedChildSrcDomain($domain) {
329
+        $this->allowedChildSrcDomains[] = $domain;
330
+        return $this;
331
+    }
332
+
333
+    /**
334
+     * Remove the specified allowed child src domain from the allowed domains.
335
+     *
336
+     * @param string $domain
337
+     * @return $this
338
+     * @since 8.1.0
339
+     * @deprecated 15.0.0 use the WorkerSrcDomains or FrameDomain
340
+     */
341
+    public function disallowChildSrcDomain($domain) {
342
+        $this->allowedChildSrcDomains = array_diff($this->allowedChildSrcDomains, [$domain]);
343
+        return $this;
344
+    }
345
+
346
+    /**
347
+     * Domains which can embed an iFrame of the Nextcloud instance
348
+     *
349
+     * @param string $domain
350
+     * @return $this
351
+     * @since 13.0.0
352
+     */
353
+    public function addAllowedFrameAncestorDomain($domain) {
354
+        $this->allowedFrameAncestors[] = $domain;
355
+        return $this;
356
+    }
357
+
358
+    /**
359
+     * Domains which can embed an iFrame of the Nextcloud instance
360
+     *
361
+     * @param string $domain
362
+     * @return $this
363
+     * @since 13.0.0
364
+     */
365
+    public function disallowFrameAncestorDomain($domain) {
366
+        $this->allowedFrameAncestors = array_diff($this->allowedFrameAncestors, [$domain]);
367
+        return $this;
368
+    }
369
+
370
+    /**
371
+     * Domain from which workers can be loaded
372
+     *
373
+     * @param string $domain
374
+     * @return $this
375
+     * @since 15.0.0
376
+     */
377
+    public function addAllowedWorkerSrcDomain(string $domain) {
378
+        $this->allowedWorkerSrcDomains[] = $domain;
379
+        return $this;
380
+    }
381
+
382
+    /**
383
+     * Remove domain from which workers can be loaded
384
+     *
385
+     * @param string $domain
386
+     * @return $this
387
+     * @since 15.0.0
388
+     */
389
+    public function disallowWorkerSrcDomain(string $domain) {
390
+        $this->allowedWorkerSrcDomains = array_diff($this->allowedWorkerSrcDomains, [$domain]);
391
+        return $this;
392
+    }
393
+
394
+    /**
395
+     * Domain to where forms can submit
396
+     *
397
+     * @since 17.0.0
398
+     *
399
+     * @return $this
400
+     */
401
+    public function addAllowedFormActionDomain(string $domain) {
402
+        $this->allowedFormActionDomains[] = $domain;
403
+        return $this;
404
+    }
405
+
406
+    /**
407
+     * Remove domain to where forms can submit
408
+     *
409
+     * @return $this
410
+     * @since 17.0.0
411
+     */
412
+    public function disallowFormActionDomain(string $domain) {
413
+        $this->allowedFormActionDomains = array_diff($this->allowedFormActionDomains, [$domain]);
414
+        return $this;
415
+    }
416
+
417
+    /**
418
+     * Add location to report CSP violations to
419
+     *
420
+     * @param string $location
421
+     * @return $this
422
+     * @since 15.0.0
423
+     */
424
+    public function addReportTo(string $location) {
425
+        $this->reportTo[] = $location;
426
+        return $this;
427
+    }
428
+
429
+    /**
430
+     * Get the generated Content-Security-Policy as a string
431
+     * @return string
432
+     * @since 8.1.0
433
+     */
434
+    public function buildPolicy() {
435
+        $policy = "default-src 'none';";
436
+        $policy .= "base-uri 'none';";
437
+        $policy .= "manifest-src 'self';";
438
+
439
+        if (!empty($this->allowedScriptDomains) || $this->inlineScriptAllowed || $this->evalScriptAllowed) {
440
+            $policy .= 'script-src ';
441
+            if (is_string($this->useJsNonce)) {
442
+                $policy .= '\'nonce-'.base64_encode($this->useJsNonce).'\'';
443
+                $allowedScriptDomains = array_flip($this->allowedScriptDomains);
444
+                unset($allowedScriptDomains['\'self\'']);
445
+                $this->allowedScriptDomains = array_flip($allowedScriptDomains);
446
+                if (count($allowedScriptDomains) !== 0) {
447
+                    $policy .= ' ';
448
+                }
449
+            }
450
+            if (is_array($this->allowedScriptDomains)) {
451
+                $policy .= implode(' ', $this->allowedScriptDomains);
452
+            }
453
+            if ($this->inlineScriptAllowed) {
454
+                $policy .= ' \'unsafe-inline\'';
455
+            }
456
+            if ($this->evalScriptAllowed) {
457
+                $policy .= ' \'unsafe-eval\'';
458
+            }
459
+            $policy .= ';';
460
+        }
461
+
462
+        if (!empty($this->allowedStyleDomains) || $this->inlineStyleAllowed) {
463
+            $policy .= 'style-src ';
464
+            if (is_array($this->allowedStyleDomains)) {
465
+                $policy .= implode(' ', $this->allowedStyleDomains);
466
+            }
467
+            if ($this->inlineStyleAllowed) {
468
+                $policy .= ' \'unsafe-inline\'';
469
+            }
470
+            $policy .= ';';
471
+        }
472
+
473
+        if (!empty($this->allowedImageDomains)) {
474
+            $policy .= 'img-src ' . implode(' ', $this->allowedImageDomains);
475
+            $policy .= ';';
476
+        }
477
+
478
+        if (!empty($this->allowedFontDomains)) {
479
+            $policy .= 'font-src ' . implode(' ', $this->allowedFontDomains);
480
+            $policy .= ';';
481
+        }
482
+
483
+        if (!empty($this->allowedConnectDomains)) {
484
+            $policy .= 'connect-src ' . implode(' ', $this->allowedConnectDomains);
485
+            $policy .= ';';
486
+        }
487
+
488
+        if (!empty($this->allowedMediaDomains)) {
489
+            $policy .= 'media-src ' . implode(' ', $this->allowedMediaDomains);
490
+            $policy .= ';';
491
+        }
492
+
493
+        if (!empty($this->allowedObjectDomains)) {
494
+            $policy .= 'object-src ' . implode(' ', $this->allowedObjectDomains);
495
+            $policy .= ';';
496
+        }
497
+
498
+        if (!empty($this->allowedFrameDomains)) {
499
+            $policy .= 'frame-src ';
500
+            $policy .= implode(' ', $this->allowedFrameDomains);
501
+            $policy .= ';';
502
+        }
503
+
504
+        if (!empty($this->allowedChildSrcDomains)) {
505
+            $policy .= 'child-src ' . implode(' ', $this->allowedChildSrcDomains);
506
+            $policy .= ';';
507
+        }
508
+
509
+        if (!empty($this->allowedFrameAncestors)) {
510
+            $policy .= 'frame-ancestors ' . implode(' ', $this->allowedFrameAncestors);
511
+            $policy .= ';';
512
+        } else {
513
+            $policy .= 'frame-ancestors \'none\';';
514
+        }
515
+
516
+        if (!empty($this->allowedWorkerSrcDomains)) {
517
+            $policy .= 'worker-src ' . implode(' ', $this->allowedWorkerSrcDomains);
518
+            $policy .= ';';
519
+        }
520
+
521
+        if (!empty($this->allowedFormActionDomains)) {
522
+            $policy .= 'form-action ' . implode(' ', $this->allowedFormActionDomains);
523
+            $policy .= ';';
524
+        }
525
+
526
+        if (!empty($this->reportTo)) {
527
+            $policy .= 'report-uri ' . implode(' ', $this->reportTo);
528
+            $policy .= ';';
529
+        }
530
+
531
+        return rtrim($policy, ';');
532
+    }
533 533
 }
Please login to merge, or discard this patch.