Skip to content

Commit 44c8c5a

Browse files
Ricky-rickbarryvdh
authored andcommitted
Option to use debugbar with content-security-policy headers (barryvdh#569)
* Option to use debugbar with content-security-policy headers * Update default value for csp-compatible Users that have don't update the config file will use this default,
1 parent b45cee9 commit 44c8c5a

File tree

5 files changed

+94
-2
lines changed

5 files changed

+94
-2
lines changed

config/debugbar.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,17 @@
159159
],
160160
],
161161

162+
/*
163+
|--------------------------------------------------------------------------
164+
| Content security policy compatible
165+
|--------------------------------------------------------------------------
166+
|
167+
| If you have set a content security policy in your header you need to set
168+
| this variable to true. You need to add "img-src:'self' data:" to your
169+
| csp header. Note: Storage needs to be enabled for this to work.
170+
|
171+
*/
172+
'csp-compatible' => false,
162173
/*
163174
|--------------------------------------------------------------------------
164175
| Inject Debugbar in Response

src/Controllers/AssetController.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,17 @@ public function css()
4444
return $this->cacheResponse($response);
4545
}
4646

47+
public function init()
48+
{
49+
$renderer = $this->debugbar->getJavascriptRenderer();
50+
$content = $renderer->renderInitScript();
51+
$response = new Response(
52+
$content, 200, [
53+
'Content-Type' => 'text/javascript',
54+
]
55+
);
56+
return $this->cacheResponse($response);
57+
}
4758
/**
4859
* Cache the response 1 year (31536000 sec)
4960
*/

src/JavascriptRenderer.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,16 @@ public function renderHead()
5252
$html = "<link rel='stylesheet' type='text/css' property='stylesheet' href='{$cssRoute}'>";
5353
$html .= "<script type='text/javascript' src='{$jsRoute}'></script>";
5454

55+
return $html;
56+
}
57+
protected function getJsInitializationCode()
58+
{
59+
$js = '';
5560
if ($this->isJqueryNoConflictEnabled()) {
56-
$html .= '<script type="text/javascript">jQuery.noConflict(true);</script>' . "\n";
61+
$js .= 'jQuery.noConflict(true);' . "\n";
5762
}
5863

59-
return $html;
64+
return $js . parent::getJsInitializationCode();
6065
}
6166

6267
/**
@@ -97,6 +102,24 @@ public function dumpAssetsToString($type)
97102
return $content;
98103
}
99104

105+
/**
106+
* Return the init script as a string
107+
*
108+
* @return string
109+
*/
110+
public function renderInitScript()
111+
{
112+
$openHandlerUrl = route('debugbar.openhandler');
113+
$this->setOpenHandlerUrl($openHandlerUrl);
114+
$content = $this->getJsInitializationCode();
115+
$content .= sprintf(
116+
"%s.loadDataSet($(\"span[data-debugbar-id]\").attr(\"data-debugbar-id\"), \"(ajax)\");\n",
117+
$this->variableName,
118+
$this->openHandlerClass,
119+
json_encode(array("url" => $this->openHandlerUrl))
120+
);
121+
return $content;
122+
}
100123
/**
101124
* Makes a URI relative to another
102125
*

src/LaravelDebugbar.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,12 @@ public function modifyResponse(Request $request, Response $response)
712712
} catch (\Exception $e) {
713713
$app['log']->error('Debugbar exception: ' . $e->getMessage());
714714
}
715+
} elseif ($app['config']->get('debugbar.inject', true) && $app['config']->get('debugbar.csp-compatible', false)) {
716+
try {
717+
$this->injectDebugbarCSP($response);
718+
} catch (\Exception $e) {
719+
$app['log']->error('Debugbar exception: ' . $e->getMessage());
720+
}
715721
} elseif ($app['config']->get('debugbar.inject', true)) {
716722
try {
717723
$this->injectDebugbar($response);
@@ -836,6 +842,43 @@ public function injectDebugbar(Response $response)
836842
$response->headers->remove('Content-Length');
837843
}
838844

845+
public function injectDebugbarCSP(Response $response)
846+
{
847+
if (!$this->app['config']->get('debugbar.storage.enabled')) {
848+
throw new \Exception('Store needs to be enabled for content security policy');
849+
}
850+
//collect and store data
851+
$this->collect();
852+
853+
$content = $response->getContent();
854+
855+
$renderer = $this->getJavascriptRenderer();
856+
if ($this->getStorage()) {
857+
$openHandlerUrl = route('debugbar.openhandler');
858+
$renderer->setOpenHandlerUrl($openHandlerUrl);
859+
}
860+
861+
$initRoute = route('debugbar.assets.init', [
862+
'v' => filemtime(config_path('debugbar.php'))
863+
]);
864+
865+
$initRoute = preg_replace('/\Ahttps?:/', '', $initRoute);
866+
867+
$scriptContent = $renderer->renderHead() .
868+
"<span data-debugbar-id='{$this->getCurrentRequestId()}'></span>
869+
<script type='text/javascript' src='{$initRoute}'></script>";
870+
871+
$pos = strripos($content, '</body>');
872+
if (false !== $pos) {
873+
$content = substr($content, 0, $pos) . $scriptContent . substr($content, $pos);
874+
} else {
875+
$content = $content . $scriptContent;
876+
}
877+
878+
// Update the new content and reset the content length
879+
$response->setContent($content);
880+
$response->headers->remove('Content-Length');
881+
}
839882
/**
840883
* Disable the Debugbar
841884
*/

src/ServiceProvider.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ public function boot()
100100
'uses' => 'AssetController@js',
101101
'as' => 'debugbar.assets.js',
102102
]);
103+
$router->get('assets/init', [
104+
'uses' => 'AssetController@init',
105+
'as' => 'debugbar.assets.init',
106+
]);
103107
});
104108

105109
if ($app->runningInConsole() || $app->environment('testing')) {

0 commit comments

Comments
 (0)