NelmioCorsBundle
NelmioCorsBundle copied to clipboard
Environment variable in configuration set to *
Hi,
I am using environment variable to set the allow_origin
setting. But it is not working when I set the env var to * (CORS_ALLOW_ORIGIN=*
)
Here is my nelmio_cors.yaml
nelmio_cors:
defaults:
allow_credentials: false
allow_headers: ['*']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
hosts: []
max_age: 3600
origin_regex: false
paths:
'^/': ~
After an hour of debugging I found out when you are processing configuration in the NelmioCorsExtension
you are over writing ['*']
with true
which is then used by CorsListener::checkOrigin
. Unfortunately the env vars are not process by the time NelmioCorsExtension::load
is fired which results in $defaults
configuration to be:
array (
'allow_origin' =>
array (
0 => 'env_CORS_ALLOW_ORIGIN_e4d0f6b476ece54b1defc34ac2cefad8',
),
'allow_credentials' => false,
'allow_headers' =>
array (
0 => '*',
),
'expose_headers' =>
array (
),
'allow_methods' =>
array (
0 => 'GET',
1 => 'OPTIONS',
2 => 'POST',
3 => 'PUT',
4 => 'PATCH',
5 => 'DELETE',
),
'max_age' => 3600,
'hosts' =>
array (
),
'origin_regex' => false,
'forced_allow_origin_value' => NULL,
)
So this mean the allow_origin
is not being over written with true
, which results in CorsListener::checkOrigin
not working as expected. Is there any other way we could set allow_origin
to be a *
with env var?
I am using:
- PHP 7.2
- Symfony 4
- nelmio/NelmioCorsBundle 1.5.4
Can confirm, stumbled across the same problem. I had to directly edit the yaml file to get it working. I should have checked here before wasting my time searching!
The error in the logs when using the .env
file:
request.CRITICAL: Uncaught PHP Exception ErrorException: "Warning: preg_match(): Compilation failed: nothing to repeat at offset 0" at /var/www/html/mysite.com/vendor/nelmio/cors-bundle/EventListener/CorsListener.php line 193 {"exception":"[object] (ErrorException(code: 0): Warning: preg_match(): Compilation failed: nothing to repeat at offset 0 at /var/www/html/mysite.com/vendor/nelmio/cors-bundle/EventListener/CorsListener.php:193)"} []
In the .env
file I've tried the following configurations before overriding it in the yaml:
-
'*'
-
*
-
['*']
I have the same problem. It has also been solved by editing the yaml.
@nataliaAznar Could you please share your .yaml with us? I'm still stuck with that issue and I can't figure it out.
Yes, of course.
I have solved it just ignoring de CORS_ALLOW_ORIGIN of the .env file, an writting it directly in the yaml:
nelmio_cors:
defaults:
origin_regex: true
allow_origin: ['*']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['*']
max_age: 3600
paths:
'^/': ~
Thank you @nataliaAznar ! Well I guess my problem is different then. I cannot specify the wildcard '*' as my front end display this error:
4/login:1 Failed to load https://API-URL.com/api/login_check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'https://FRONT-URL.com' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
I tried to set:
nelmio_cors:
defaults:
allow_credentials: true
origin_regex: true
# allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
allow_origin: ['https://FRONT-URL.com']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization']
max_age: 3600
paths:
'^/': ~
But I still got that wildcard '*' error. It's like NelmioCors is not rewriting the response header.
Have you try without the "allow_credentials: true" ?
Yes, but no better luck.
Interesting to note here:
In order to validate the Origin
header against the allowed origins, the current algorithm operates as follows:
...
if ($options['allow_origin'] === true) return true;
if ($options['origin_regex'] === true) {
// origin regex matching
foreach($options['allow_origin'] as $originRegexp) {
if (preg_match('{'.$originRegexp.'}i', $origin)) {
return true;
}
}
} else {
...
The regex provides the desired *
value for the pattern, which translates to zero or more times.
The problem in this scenario, if origin_regex
is equal to true, is that there is no leader for the zero or more times, i.e. .*
, and then you get a preg_match
error:
Uncaught PHP Exception ErrorException: "Warning: preg_match(): Compilation failed: nothing to repeat at offset 0" at /var/task/vendor/nelmio/cors-bundle/EventListener/CorsListener.php line 193
In conclusion, either
- set the
allow_origin
to true, or - set the
origin_regex
to true, and provide.*
as an item in theallow_origin
array (noting the leading.
) - set the
origin_regex
to false and let the*
match
Great bundle, but please add this limitation in the doc, I get mad trying to compile CORS_ALLOW_ORIGIN=*
;)
Dot(.
) work for me:
nelmio_cors:
defaults:
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
origin_regex: true
.env
file
CORS_ALLOW_ORIGIN=.
I think it should be at least CORS_ALLOW_ORIGIN=.* Because * means to repeat something - and there is nothing to repeat - because nothing is before * Have you tried that?
This is still not solved. I'm using Symfony 5.1.7 and nelmio/cors-bundle
v2.1 with next configuration:
.env
###> nelmio/cors-bundle ###
CORS_ALLOW_ORIGIN=.*
###< nelmio/cors-bundle ###
nelmio_cors.yaml
nelmio_cors:
defaults:
origin_regex: true
allow_credentials: true
allow_origin: ['*']
allow_methods: ['*']
allow_headers: ['*']
expose_headers: ['*']
forced_allow_origin_value: ~
max_age: 3600
paths:
'^/': ~
But still getting an error: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ‘http://localhost:3000/.well-known/mercure?topic=http%3A%2F%2Fexample.com%2Fbooks%2F%7Bid%7D’. (Reason: Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’).
? quelqu'un a trouvez une solution à cette problématique?
Four years on and this is still an issue. I assume it's due to a limitation in Symfony and the way environment variables are loaded.
Allowing *
for origin is not a solution. It does not achieve secure CORS.
The only solution we've come up with so far is to hard code the value into different parameter files (local, staging and production) rather than configuring once and using and environment variable.
Anyone got any other solutions which actually achieve the goal of setting via environment variables?
As far as I can tell this was solved by 2.0.0 in https://github.com/nelmio/NelmioCorsBundle/commit/2c463446186b4fa0cef64f8783372de57aae6f46 - if anyone still has this issue with the latest version please open a new issue with more details.
@alexbaileyuk I believe your issue is more https://github.com/nelmio/NelmioCorsBundle/issues/148