Skip to content

Commit cd33ed0

Browse files
committed
[WebProfilerBundle] Fix CORS ajax security issues
1 parent eb23f05 commit cd33ed0

File tree

6 files changed

+21
-8
lines changed

6 files changed

+21
-8
lines changed

src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/Configuration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public function getConfigTreeBuilder()
4545
->end()
4646
->end()
4747
->booleanNode('intercept_redirects')->defaultFalse()->end()
48+
->booleanNode('enable_cors')->defaultFalse()->end()
4849
->scalarNode('excluded_ajax_paths')->defaultValue('^/(app(_[\\w]+)?\\.php/)?_wdt')->end()
4950
->end()
5051
;

src/Symfony/Bundle/WebProfilerBundle/DependencyInjection/WebProfilerExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public function load(array $configs, ContainerBuilder $container)
4949
if ($config['toolbar'] || $config['intercept_redirects']) {
5050
$loader->load('toolbar.xml');
5151
$container->getDefinition('web_profiler.debug_toolbar')->replaceArgument(5, $config['excluded_ajax_paths']);
52+
$container->getDefinition('web_profiler.debug_toolbar')->replaceArgument(6, $config['enable_cors']);
5253
$container->setParameter('web_profiler.debug_toolbar.intercept_redirects', $config['intercept_redirects']);
5354
$container->setParameter('web_profiler.debug_toolbar.mode', $config['toolbar'] ? WebDebugToolbarListener::ENABLED : WebDebugToolbarListener::DISABLED);
5455
}

src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,17 @@ class WebDebugToolbarListener implements EventSubscriberInterface
4040
protected $mode;
4141
protected $position;
4242
protected $excludedAjaxPaths;
43+
protected $enableCors;
4344

44-
public function __construct(\Twig_Environment $twig, $interceptRedirects = false, $mode = self::ENABLED, $position = 'bottom', UrlGeneratorInterface $urlGenerator = null, $excludedAjaxPaths = '^/bundles|^/_wdt')
45+
public function __construct(\Twig_Environment $twig, $interceptRedirects = false, $mode = self::ENABLED, $position = 'bottom', UrlGeneratorInterface $urlGenerator = null, $excludedAjaxPaths = '^/bundles|^/_wdt', $enableCors = false)
4546
{
4647
$this->twig = $twig;
4748
$this->urlGenerator = $urlGenerator;
4849
$this->interceptRedirects = (bool) $interceptRedirects;
4950
$this->mode = (int) $mode;
5051
$this->position = $position;
5152
$this->excludedAjaxPaths = $excludedAjaxPaths;
53+
$this->enableCors = $enableCors;
5254
}
5355

5456
public function isEnabled()
@@ -123,6 +125,7 @@ protected function injectToolbar(Response $response, Request $request)
123125
'excluded_ajax_paths' => $this->excludedAjaxPaths,
124126
'token' => $response->headers->get('X-Debug-Token'),
125127
'request' => $request,
128+
'enable_cors' => $this->enableCors,
126129
)
127130
))."\n";
128131
$content = substr($content, 0, $pos).$toolbar.substr($content, $pos);

src/Symfony/Bundle/WebProfilerBundle/Resources/config/toolbar.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<argument>%web_profiler.debug_toolbar.position%</argument>
1818
<argument type="service" id="router" on-invalid="ignore" />
1919
<argument /> <!-- paths that should be excluded from the AJAX requests shown in the toolbar -->
20+
<argument /> <!-- enable CORS AJAX requests shown in the toolbar -->
2021
</service>
2122
</services>
2223
</container>

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,15 @@
208208
{% if excluded_ajax_paths is defined %}
209209
if (window.XMLHttpRequest && XMLHttpRequest.prototype.addEventListener) {
210210
var proxied = XMLHttpRequest.prototype.open;
211+
var enable_cors = {{ enable_cors ? 'true' : 'false' }};
211212
212213
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
213214
var self = this;
214215
215216
/* prevent logging AJAX calls to static and inline files, like templates */
216217
var path = url;
218+
var is_cors_request = false;
219+
217220
if (url.substr(0, 1) === '/') {
218221
if (0 === url.indexOf('{{ request.basePath|e('js') }}')) {
219222
path = url.substr({{ request.basePath|length }});
@@ -222,8 +225,11 @@
222225
else if (0 === url.indexOf('{{ (request.schemeAndHttpHost ~ request.basePath)|e('js') }}')) {
223226
path = url.substr({{ (request.schemeAndHttpHost ~ request.basePath)|length }});
224227
}
228+
else if (!enable_cors) {
229+
is_cors_request = true;
230+
}
225231
226-
if (!path.match(new RegExp({{ excluded_ajax_paths|json_encode|raw }}))) {
232+
if ((!is_cors_request || enable_cors) && !path.match(new RegExp({{ excluded_ajax_paths|json_encode|raw }}))) {
227233
var stackElement = {
228234
loading: true,
229235
error: false,

src/Symfony/Bundle/WebProfilerBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ public function testConfigTree($options, $results)
3131
public function getDebugModes()
3232
{
3333
return array(
34-
array(array(), array('intercept_redirects' => false, 'toolbar' => false, 'position' => 'bottom', 'excluded_ajax_paths' => '^/(app(_[\\w]+)?\\.php/)?_wdt')),
35-
array(array('intercept_redirects' => true), array('intercept_redirects' => true, 'toolbar' => false, 'position' => 'bottom', 'excluded_ajax_paths' => '^/(app(_[\\w]+)?\\.php/)?_wdt')),
36-
array(array('intercept_redirects' => false), array('intercept_redirects' => false, 'toolbar' => false, 'position' => 'bottom', 'excluded_ajax_paths' => '^/(app(_[\\w]+)?\\.php/)?_wdt')),
37-
array(array('toolbar' => true), array('intercept_redirects' => false, 'toolbar' => true, 'position' => 'bottom', 'excluded_ajax_paths' => '^/(app(_[\\w]+)?\\.php/)?_wdt')),
38-
array(array('position' => 'top'), array('intercept_redirects' => false, 'toolbar' => false, 'position' => 'top', 'excluded_ajax_paths' => '^/(app(_[\\w]+)?\\.php/)?_wdt')),
39-
array(array('excluded_ajax_paths' => 'test'), array('intercept_redirects' => false, 'toolbar' => false, 'position' => 'bottom', 'excluded_ajax_paths' => 'test')),
34+
array(array(), array('intercept_redirects' => false, 'toolbar' => false, 'position' => 'bottom', 'excluded_ajax_paths' => '^/(app(_[\\w]+)?\\.php/)?_wdt', 'enable_cors' => false)),
35+
array(array('intercept_redirects' => true), array('intercept_redirects' => true, 'toolbar' => false, 'position' => 'bottom', 'excluded_ajax_paths' => '^/(app(_[\\w]+)?\\.php/)?_wdt', 'enable_cors' => false)),
36+
array(array('intercept_redirects' => false), array('intercept_redirects' => false, 'toolbar' => false, 'position' => 'bottom', 'excluded_ajax_paths' => '^/(app(_[\\w]+)?\\.php/)?_wdt', 'enable_cors' => false)),
37+
array(array('toolbar' => true), array('intercept_redirects' => false, 'toolbar' => true, 'position' => 'bottom', 'excluded_ajax_paths' => '^/(app(_[\\w]+)?\\.php/)?_wdt', 'enable_cors' => false)),
38+
array(array('position' => 'top'), array('intercept_redirects' => false, 'toolbar' => false, 'position' => 'top', 'excluded_ajax_paths' => '^/(app(_[\\w]+)?\\.php/)?_wdt', 'enable_cors' => false)),
39+
array(array('excluded_ajax_paths' => 'test'), array('intercept_redirects' => false, 'toolbar' => false, 'position' => 'bottom', 'excluded_ajax_paths' => 'test', 'enable_cors' => false)),
40+
array(array('enable_cors' => true), array('intercept_redirects' => false, 'toolbar' => false, 'position' => 'bottom', 'excluded_ajax_paths' => '^/(app(_[\\w]+)?\\.php/)?_wdt', 'enable_cors' => true)),
4041
);
4142
}
4243
}

0 commit comments

Comments
 (0)