Skip to content

Commit e445372

Browse files
committed
fix: split large Content-Security-Policy headers over multiple HTTP headers
Signed-off-by: niv <nicolas.varlot@ac-versailles.fr>
1 parent be15904 commit e445372

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

lib/private/AppFramework/Http/Output.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,34 @@ public function setReadfile($path) {
4747
*/
4848
#[\Override]
4949
public function setHeader($header) {
50+
// Apache mod_proxy_fcgi parses FCGI response headers with a buffer
51+
// hardcoded at HUGE_STRING_LEN (8192 bytes in httpd.h); 7800 leaves
52+
// a safety margin for the status line and surrounding header bytes.
53+
$maxLen = 7800;
54+
if (strlen($header) > $maxLen) {
55+
foreach (['Content-Security-Policy:', 'Feature-Policy:'] as $prefix) {
56+
if (str_starts_with($header, $prefix)) {
57+
$value = ltrim(substr($header, strlen($prefix)));
58+
$directives = array_filter(array_map(trim(...), explode(';', $value)));
59+
$segment = '';
60+
$first = true;
61+
foreach ($directives as $directive) {
62+
$candidate = $segment === '' ? $directive : $segment . ';' . $directive;
63+
if (strlen($prefix . ' ' . $candidate . ';') > $maxLen && $segment !== '') {
64+
header($prefix . ' ' . $segment . ';', $first);
65+
$first = false;
66+
$segment = $directive;
67+
} else {
68+
$segment = $candidate;
69+
}
70+
}
71+
if ($segment !== '') {
72+
header($prefix . ' ' . $segment . ';', $first);
73+
}
74+
return;
75+
}
76+
}
77+
}
5078
header($header);
5179
}
5280

0 commit comments

Comments
 (0)