Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debugbar Not Showing Due To CSP #1317

Open
sys-auditing opened this issue Jun 3, 2022 · 9 comments
Open

Debugbar Not Showing Due To CSP #1317

sys-auditing opened this issue Jun 3, 2022 · 9 comments
Labels

Comments

@sys-auditing
Copy link

sys-auditing commented Jun 3, 2022

Hi,

i'm using the laravel-debugbar and works like a charm, but when adding CSP the debugbar stop showing.

Laravel :
"laravel/framework": "^8.0"
"spatie/laravel-csp": "2.6.4",

Debugbar :
"barryvdh/laravel-debugbar": "^3.5"

Thank's for the help

@robov
Copy link

robov commented Jul 4, 2022

This is probably a problem with a missing nounce
@barryvdh did you ever find a solution for this (except for enabling unsafe-inline in debug state) ?

@luckydonald
Copy link

The bot marked the old ticket as stale: #1016

@stale
Copy link

stale bot commented Nov 2, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If this issue is still present on the latest version of this library on supported Laravel versions, please let us know by replying to this issue so we can investigate further.
Thank you for your contribution! Apologies for any delayed response on our side.

@stale stale bot added the stale label Nov 2, 2022
@luckydonald
Copy link

.

@stale stale bot removed the stale label Nov 4, 2022
@luckydonald
Copy link

luckydonald commented Jan 5, 2023

I mean I could just use hashes to allow just the stuff it writes.

The problem is phpdebugbar.addDataSet({…}, "…") in the last added script tag.

Which I could work around by adding this in a middleware:

            $content = $response->content();
            $debugBarVar = 'phpdebugbar';  // this was coming from some config, but I forgot from where.
            preg_match('/(?P<openScriptTagStart><script )(?P<openScriptTagEnd>.*?>)(?P<scriptContentBefore>\n.*?)\n'.$debugBarVar.'\.addDataSet\((?P<data>.+), "(?P<param>\w+)"\);(?P<scriptContentAfter>\n.*?)(?P<closeScriptTag><\/script>)/s', $response->content(), $matches);
            $openScriptTagStart = $matches['openScriptTagStart'];
            $data = $matches['data'];
            $param = $matches['param'];
            $openScriptTagEnd = $matches['openScriptTagEnd'];
            $scriptContentBefore = $matches['scriptContentBefore'];
            $scriptContentAfter = $matches['scriptContentAfter'];
            $closeScriptTag = $matches['closeScriptTag'];
            $dataEncoded = htmlspecialchars($data);
            $paramEncoded = htmlspecialchars($param);
            $old = $matches[0];
            $new = "$openScriptTagStart data-$debugBarVar-data=\"$dataEncoded\" data-$debugBarVar-param=\"$paramEncoded\" $openScriptTagEnd{$scriptContentBefore}\n";
            $new .= "var {$debugBarVar}Data = document.querySelector('script[data-$debugBarVar-data][data-$debugBarVar-param]').attributes;\n";
            $new .= "$debugBarVar.addDataSet(JSON.parse({$debugBarVar}Data['data-$debugBarVar-data'].value), {$debugBarVar}Data['data-$debugBarVar-param'].value);\n";
            $new .= "{$scriptContentAfter}$closeScriptTag";
            $content = $content->replace($old, $new)->value();
            $original = null;
            if ($response instanceof \Illuminate\Http\Response && $response->getOriginalContent()) {
                $original = $response->getOriginalContent();
            }

            // Update the new content and reset the content length
            $response->setContent($content);
            $response->headers->remove('Content-Length');

            // Restore original response (eg. the View or Ajax data)
            if ($original) {
                $response->original = $original;
            }

What it does is using a regex (uh oh) to grab the values of that.
Then those get applied as two attributes to the script tag instead: data-phpdebugbar-data="{…}" and data-phpdebugbar-param="…".

It can easily be loaded with

JSON.parse(document.querySelector('script[data-phpdebugbar-data]').attributes['data-$debugBarVar-data'].value))

Now the content of the <script> does no longer change, and a hash can be used to whitelist the occurrence in the CSP;
In my case '\'sha256-Q59u6hqnWqFUgu6e2Pg5p1xxto/mrNsJbgpsZsCVVY4=\''.


The only problem remaining now, is to get the middleware in the correct order so $response->content() actually is with the debug bar already injected.

@dasch88
Copy link

dasch88 commented Jan 18, 2023

I am running into this too. I could really use a clean solution to setting a nonce for any styles/scripts that debugbar injects inline. This seems to be a recurring theme

@ultrono
Copy link

ultrono commented Feb 5, 2023

Only semi workaround for this (when using spatie/laravel-csp) is to either:

  • disable it locally via setting CSP_ENABLED to false
  • report only locally i.e. call $this->reportOnly() within your policy definition class

Both options will allow debug bar to display.

@stale
Copy link

stale bot commented Jun 18, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If this issue is still present on the latest version of this library on supported Laravel versions, please let us know by replying to this issue so we can investigate further.
Thank you for your contribution! Apologies for any delayed response on our side.

@stale stale bot added the stale label Jun 18, 2023
@parallels999
Copy link
Contributor

What about #1464?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants