Skip to content

Commit 2a71666

Browse files
authored
Add CSP support to Javascript renderer (php-debugbar#439)
* Add CSP support to Javascript renderer * Use parameters to set CSP nonce
1 parent 1a873d7 commit 2a71666

File tree

1 file changed

+48
-4
lines changed

1 file changed

+48
-4
lines changed

src/DebugBar/JavascriptRenderer.php

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class JavascriptRenderer
8282

8383
protected $openHandlerUrl;
8484

85+
protected $cspNonce;
86+
8587
/**
8688
* @param \DebugBar\DebugBar $debugBar
8789
* @param string $baseUrl
@@ -183,6 +185,9 @@ public function setOptions(array $options)
183185
if (array_key_exists('open_handler_url', $options)) {
184186
$this->setOpenHandlerUrl($options['open_handler_url']);
185187
}
188+
if (array_key_exists('csp_nonce', $options)) {
189+
$this->setCspNonce($options['csp_nonce']);
190+
}
186191
}
187192

188193
/**
@@ -606,6 +611,28 @@ public function getOpenHandlerUrl()
606611
return $this->openHandlerUrl;
607612
}
608613

614+
/**
615+
* Sets the CSP Nonce (or remove it by setting to null)
616+
*
617+
* @param string|null $nonce
618+
* @return $this
619+
*/
620+
public function setCspNonce($nonce = null)
621+
{
622+
$this->cspNonce = $nonce;
623+
return $this;
624+
}
625+
626+
/**
627+
* Get the CSP Nonce
628+
*
629+
* @return string|null
630+
*/
631+
public function getCspNonce()
632+
{
633+
return $this->cspNonce;
634+
}
635+
609636
/**
610637
* Add assets stored in files to render in the head
611638
*
@@ -905,6 +932,8 @@ public function renderHead()
905932
list($cssFiles, $jsFiles, $inlineCss, $inlineJs, $inlineHead) = $this->getAssets(null, self::RELATIVE_URL);
906933
$html = '';
907934

935+
$nonce = $this->getNonceAttribute();
936+
908937
foreach ($cssFiles as $file) {
909938
$html .= sprintf('<link rel="stylesheet" type="text/css" href="%s">' . "\n", $file);
910939
}
@@ -918,15 +947,15 @@ public function renderHead()
918947
}
919948

920949
foreach ($inlineJs as $content) {
921-
$html .= sprintf('<script type="text/javascript">%s</script>' . "\n", $content);
950+
$html .= sprintf('<script type="text/javascript" %s>%s</script>' . "\n", $nonce, $content);
922951
}
923952

924953
foreach ($inlineHead as $content) {
925954
$html .= $content . "\n";
926955
}
927956

928957
if ($this->enableJqueryNoConflict && !$this->useRequireJs) {
929-
$html .= '<script type="text/javascript">jQuery.noConflict(true);</script>' . "\n";
958+
$html .= '<script type="text/javascript"' . $nonce . '>jQuery.noConflict(true);</script>' . "\n";
930959
}
931960

932961
return $html;
@@ -1013,10 +1042,12 @@ public function render($initialize = true, $renderStackedData = true)
10131042
$suffix = !$initialize ? '(ajax)' : null;
10141043
$js .= $this->getAddDatasetCode($this->debugBar->getCurrentRequestId(), $this->debugBar->getData(), $suffix);
10151044

1045+
$nonce = $this->getNonceAttribute();
1046+
10161047
if ($this->useRequireJs){
1017-
return "<script type=\"text/javascript\">\nrequire(['debugbar'], function(PhpDebugBar){ $js });\n</script>\n";
1048+
return "<script type=\"text/javascript\" {$nonce}>\nrequire(['debugbar'], function(PhpDebugBar){ $js });\n</script>\n";
10181049
} else {
1019-
return "<script type=\"text/javascript\">\n$js\n</script>\n";
1050+
return "<script type=\"text/javascript\" {$nonce}>\n$js\n</script>\n";
10201051
}
10211052

10221053
}
@@ -1149,4 +1180,17 @@ protected function getAddDatasetCode($requestId, $data, $suffix = null)
11491180
);
11501181
return $js;
11511182
}
1183+
1184+
/**
1185+
* If a nonce it set, create the correct attribute
1186+
* @return string
1187+
*/
1188+
protected function getNonceAttribute()
1189+
{
1190+
if ($nonce = $this->getCspNonce()) {
1191+
return 'nonce="' . $nonce .'"';
1192+
}
1193+
1194+
return '';
1195+
}
11521196
}

0 commit comments

Comments
 (0)