Slim 3 API is giving content security policy error

In the safari iframe 14.0 version, My one API is not working/calling and I am getting the error in the console,

Refused to load https://demo.com/admin/auth/login because it does not appear in the frame-ancestors directive of the Content Security Policy.

I am calling one API named admin/auth/login from another API named “home” and I can only debug until the execution is in the home API, once I call return $response->withRedirect($installUrl);
I am unable to debug even the first line of $installUrl and get the CSP error in the console.

Also in all the other browsers, my code is doing absolutely well, Only in mac safari 14.0 my code is not working, and getting errors in the console.

I am working in a Shopify app and in the safari iframe, I am getting this error.

I am stuck in this. Please guide me what are the fixes for this. I have tried putting some headers in .htaccess and in the slim PHP files too but got no luck at all.

If anyone knows about this scenario I would love to hear on this.

Thanks in advance.

Have you tried to apply the proper CSP (Content Security Policy) headers to the $response object?

Hello Odan,

Thank you for your reply.

Yes, I have added a middleware in my slim application and tried to give header to $response object before and after both the way.

here is the code you can check.

   $app->add(function ($request, $response, $next) {
    
    $policy = "default-src 'self'";
            
            $response->withHeader("Content-Security-Policy", $policy);
    
    
    $response = $next($request, $response);
    $response->withHeader("Content-Security-Policy", $policy);

    return $response;
});

Still, I am not getting any luck on this issue. What are your thoughts on this?

Thanks again for your help.

Please note that the response headers are immutable. Does this work?

$app->add(function ($request, $response, $next) {
    $policy = "default-src 'self'";        
    $response = $next($request, $response);
    $response = $response->withHeader("Content-Security-Policy", $policy);

    return $response;
});

Hello Odan,

Thank you for your response. Yes. This is the last modified code that I have put.

    $app->add(function ($request, $response, $next) {
        $policy = "default-src 'self'";        
        $response = $next($request, $response);
        $response = $response->withHeader("Content-Security-Policy", $policy);

        return $response;
    });

With this middleware, the header is added. When I run this line from my one API

return $response->withRedirect($installUrl);

As I am debugging on each and every line. I am not at all redirecting to the $installUrl and in the console I am having CSP errors.

(1) unrecognized CSP directive ‘worker-src’.
(2) refused to load as https:demo.com/admin/auth because it does not appear in the frame-ancestors directive of CSP.

Note that except safari iframe I am doing okay in all the other browsers.

Do you have any thoughts on this?

Thanks in advance.

I see a problem here…

because this method creates a new Response object.

Maybe refactor it like this:

return $response->withStatus(302)->withHeader('Location', $installUrl);

The correct position of the CSP middleware is very important.
Make sure that your CSP middleware is added as first to the middleware stack.

Thanks, @odan Happy to see that you found a problem.

however the code

return $response->withStatus(302)->withHeader('Location', $installUrl);

Is still not solving the issue and not allowing to be redirected to that API.

With regard to the CSP middleware & APIs position, Below-mentioned is the current code positions

$app->add(function ($request, $response, $next) {
    $policy = "default-src 'self'";        
    $response = $next($request, $response);
    $response = $response->withHeader("Content-Security-Policy", $policy);

    return $response;
});


$app->get('/', function (Request $request, Response $response) {

//some code is written here
    $installUrl = "https://{$shop}/admin/oauth/authorize?client_id={$apiKey}&scope={$scope}&redirect_uri={$redirectUri}";
    
  
   // **closed this code** return $response->withRedirect($installUrl);
    return $response->withStatus(302)->withHeader('Location', $installUrl);

});.



$app->get('/auth/shopify/callback', function (Request $request, Response $response) {

// once the $installUrl is called successfully we be redirected to this API. In all the browsers we are successful being in it, Only in safari, it is showing CSP issues.

});

Hope that this code will clear it all. And I will get some luck. What are your thoughts on this?

Thanks a lot for being with me on this.

Now I see. The issue here is not your code directly, it’s HTTP. Other than HTTP cookies, there’s nothing in the protocol specification about forwarding headers. There is no way to force the client to forward the headers in the response when making a redirect. The client needs to implement this functionality.

Oh, Thank you @odan for providing your thoughts on this. So the client is safari & we can not do anything about this, Right? Is not there any way to handle this with the existing codebase which I have shown you. Yes, I completely understand your point. But not sure then how we will run our application is safari iframe.

Hello @odan,

Sorry to ask again about this. I have just created a sample demo in core PHP and all the code is on one file with if and else conditions. Before my needed logic it goes in the IF condition and once my $install URL is complete I redirect it on the same file and now It goes to the ELSE condition.

When redirecting in the same file the headers are not creating an issue, But when redirecting from one API to another API in slim I am getting this issue.

Can you let me know your thoughts on this, please?

Thanks a lot.

Just curious and I don’t know if this is best practice. But, if you want to force pass the headers, couldn’t you include them in a post request and check for them in the API endpoint?

Hi @darkalchemy I have put the header function before the withRedirect() & also I have registedd middleware for setting the header, But I have not got any progress, Errors in the console are the same as I had certain days before. Quite struck in this.

Thanks a lot for your answer.