From 2b6d1818783b103993873661c7736431b0a07604 Mon Sep 17 00:00:00 2001 From: Jianjun Chen Date: Tue, 1 May 2018 00:01:25 +0800 Subject: [PATCH] Fix #16193 to not reflect origin header for wildcard origins --- framework/CHANGELOG.md | 2 +- framework/filters/Cors.php | 15 ++++++++++++++- tests/framework/filters/CorsTest.php | 22 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 1c27039..9e26ee6 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -3,7 +3,7 @@ Yii Framework 2 Change Log 2.0.16 under development ------------------------ - +- Bug #16193: Fixed `yii\filters\Cors` to not reflect origin header value when configured to wildcard origins. (Jianjun Chen) - Bug #16068: Fixed `yii\web\CookieCollection::has` when an expiration param is set to 'until the browser is closed' (OndrejVasicek) - Bug #16006: Handle case when `X-Forwarded-Host` header have multiple hosts separated with a comma (pgaultier) - Bug #16010: Fixed `yii\filters\ContentNegotiator` behavior when GET parameters contain an array (rugabarbo) diff --git a/framework/filters/Cors.php b/framework/filters/Cors.php index f00da60..1a62d93 100644 --- a/framework/filters/Cors.php +++ b/framework/filters/Cors.php @@ -160,9 +160,22 @@ class Cors extends ActionFilter $responseHeaders = []; // handle Origin if (isset($requestHeaders['Origin'], $this->cors['Origin'])) { - if (in_array('*', $this->cors['Origin']) || in_array($requestHeaders['Origin'], $this->cors['Origin'])) { + if (in_array($requestHeaders['Origin'], $this->cors['Origin'])) { $responseHeaders['Access-Control-Allow-Origin'] = $requestHeaders['Origin']; } + + if (in_array('*', $this->cors['Origin'])) { + // Per CORS standard(https://fetch.spec.whatwg.org), wildcard origins shouldn't be used together with credentails. + if (isset($this->cors['Access-Control-Allow-Credentials']) && $this->cors['Access-Control-Allow-Credentials']) { + if (YII_DEBUG) { + throw new Exception("Allowing credentials for wildcard origins is insecure. Please specify more restrictive origins or set 'credentials' to false in your CORS configuration."); + } else { + Yii::error("Allowing credentials for wildcard origins is insecure. Please specify more restrictive origins or set 'credentials' to false in your CORS configuration.", __METHOD__); + } + } else { + $responseHeaders['Access-Control-Allow-Origin'] = "*"; + } + } } $this->prepareAllowHeaders('Headers', $requestHeaders, $responseHeaders); diff --git a/tests/framework/filters/CorsTest.php b/tests/framework/filters/CorsTest.php index 5fb1f94..c0bc739 100644 --- a/tests/framework/filters/CorsTest.php +++ b/tests/framework/filters/CorsTest.php @@ -42,4 +42,26 @@ class CorsTest extends TestCase $request->headers->remove('Access-Control-Request-Method'); $this->assertTrue($cors->beforeAction($action)); } + + public function testWildcardOrigin() + { + $this->mockWebApplication(); + $controller = new Controller('id', Yii::$app); + $action = new Action('test', $controller); + $request = new Request(); + + $cors = new Cors([ + 'cors' => [ + 'Origin' => ['*',], + 'Access-Control-Allow-Credentials' => false, + ], + ]); + $cors->request = $request; + + $_SERVER['REQUEST_METHOD'] = 'GET'; + $_SERVER['HTTP_ORIGIN'] = 'http://foo.com'; + $this->assertTrue($cors->beforeAction($action)); + $this->assertEquals('*', $cors->response->getHeaders()->get('access-control-allow-origin')); + } + }