Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wildcard CORS with allowcredentials true

I have a project where I'm using wildcard subdomains like user.mysite.com where username is a wildcard.

In my server (PHP) I've set the following headers:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Credentials: true');

This allows me to do ajax calls from the frontend since I don't know what the domain is going to be. However I also need my cookies to be sent with the requests for maintaining sessions but when I tell AngularJS on my frontend to send the credentials I get the following message:

A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true

I understand this is for security reasons but now I have no way of session management in my app. Can anyone suggest a workaround for this?

Where I tell Angular to send credentials:

$httpProvider.defaults.withCredentials = true;

My ajax requests are being send to a different subdomain. ie the url could be billy.mysite.com but the ajax requests are being sent to api.mysite.com.

like image 236
iamjonesy Avatar asked Jul 02 '14 13:07

iamjonesy


2 Answers

@iamjonesy - You have done silly mistake.

"A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true" 

To avoid the above error just follow the steps. Suppose your api server is http://api.com . And your UI server, from where you executing ajax call, is http://ui.com

PHP header code should be like,

header('Access-Control-Allow-Origin: http://ui.com');
header('Access-Control-Allow-Credentials: true');

Put the below line in angular config.js

$httpProvider.defaults.withCredentials = true;

What I did, never set "*" as wild character to $httpProvider.defaults.withCredentials,just mention full domain name from where the ajax code is reside.

like image 186
Koushik Samanta Avatar answered Sep 25 '22 14:09

Koushik Samanta


PeeHaa is correct in the comments:

Just fetch the host of the current request and use that instead of the wildcard

That is, do something like:

header('Access-Control-Allow-Origin: '.$requestHeaders['Host']);

Don't do is this way!

This is what you've asked for exactly and it solves the problem. Basically, the equivalent of header('Access-Control-Allow-Origin: *'); However, this will create a huge security hole.

Doing this will effectively mean that any site your user enters will be able to do anything on behalf of your user without his consent or notice since you relay the Access-Control-Allow-Origin with whatever host is sent and allow this host to transmit the original user's cookie (if it is set in the browser for your API).

Instead, before relaying you should always filter the hosts. Implement some kind of whitelist-checking or regexp-checking and only if it passes, relay the Host to Access-Control-Allow-Origin.

like image 35
kojo Avatar answered Sep 21 '22 14:09

kojo