Browse Source

Fixes #15420: Handle OPTIONS request in `yii\filter\Cors` so the preflight check isn't passed trough authentication filters

tags/2.0.14
Alexander Makarov 7 years ago committed by GitHub
parent
commit
399dbce0ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      framework/CHANGELOG.md
  2. 6
      framework/filters/Cors.php
  3. 45
      tests/framework/filters/CorsTest.php

1
framework/CHANGELOG.md

@ -52,6 +52,7 @@ Yii Framework 2 Change Log
- Enh #15360: Refactored `BaseConsole::updateProgress()` (developeruz)
- Enh #15415: Added transaction/retry support for `yii\db\Command` (sergeymakinen)
- Enh: Added check to `yii\base\Model::formName()` to prevent source path disclosure when form is represented by an anonymous class (silverfire)
- Chg #15420: Handle OPTIONS request in `yii\filter\Cors` so the preflight check isn't passed trough authentication filters (michaelarnauts, leandrogehlen)
2.0.13.1 November 14, 2017

6
framework/filters/Cors.php

@ -106,6 +106,12 @@ class Cors extends ActionFilter
$responseCorsHeaders = $this->prepareHeaders($requestCorsHeaders);
$this->addCorsHeaders($this->response, $responseCorsHeaders);
if ($this->request->isOptions && $this->request->headers->has('Access-Control-Request-Method')) {
// it is CORS preflight request, respond with 200 OK without further processing
$this->response->setStatusCode(200);
return false;
}
return true;
}

45
tests/framework/filters/CorsTest.php

@ -0,0 +1,45 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yiiunit\framework\filters;
use Yii;
use yii\base\Action;
use yii\filters\Cors;
use yii\web\Controller;
use yii\web\Request;
use yiiunit\TestCase;
/**
* @group filters
*/
class CorsTest extends TestCase
{
public function testPreflight()
{
$this->mockWebApplication();
$controller = new Controller('id', Yii::$app);
$action = new Action('test', $controller);
$request = new Request();
$cors = new Cors();
$cors->request = $request;
$_SERVER['REQUEST_METHOD'] = 'OPTIONS';
$request->headers->set('Access-Control-Request-Method', 'GET');
$this->assertFalse($cors->beforeAction($action));
$this->assertEquals(200, $cors->response->getStatusCode());
$_SERVER['REQUEST_METHOD'] = 'GET';
$request->headers->set('Access-Control-Request-Method', 'GET');
$this->assertTrue($cors->beforeAction($action));
$request->headers->remove('Access-Control-Request-Method');
$this->assertTrue($cors->beforeAction($action));
}
}
Loading…
Cancel
Save