Browse Source

Fix #17878: Detect CORS AJAX requests without `X-Requested-With` in `Request::getIsAjax()`

tags/2.0.33
Igor Tarasov 5 years ago committed by GitHub
parent
commit
7f88acb313
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      framework/CHANGELOG.md
  2. 12
      framework/web/Request.php
  3. 2
      tests/framework/ChangeLogTest.php
  4. 18
      tests/framework/web/RequestTest.php

1
framework/CHANGELOG.md

@ -4,6 +4,7 @@ Yii Framework 2 Change Log
2.0.33 under development 2.0.33 under development
------------------------ ------------------------
- Bug #17878: Detect CORS AJAX requests without `X-Requested-With` in `Request::getIsAjax()` (dicrtarasov, samdark)
- Enh #17929: Actions can now have bool typed params bound (alex-code) - Enh #17929: Actions can now have bool typed params bound (alex-code)
- Enh #17827: Add `StringValidator::$strict` that can be turned off to allow any scalars (adhayward, samdark) - Enh #17827: Add `StringValidator::$strict` that can be turned off to allow any scalars (adhayward, samdark)
- Bug #16145: Fix `Html` helper `checkboxList()`, `radioList()`, `renderSelectOptions()`, `dropDownList()`, `listBox()` methods to work properly with traversable selection (samdark) - Bug #16145: Fix `Html` helper `checkboxList()`, `radioList()`, `renderSelectOptions()`, `dropDownList()`, `listBox()` methods to work properly with traversable selection (samdark)

12
framework/web/Request.php

@ -471,8 +471,8 @@ class Request extends \yii\base\Request
/** /**
* Returns whether this is an AJAX (XMLHttpRequest) request. * Returns whether this is an AJAX (XMLHttpRequest) request.
* *
* Note that jQuery doesn't set the header in case of cross domain * Note that in case of cross domain requests, browser doesn't set the X-Requested-With header by default:
* requests: https://stackoverflow.com/questions/8163703/cross-domain-ajax-doesnt-send-x-requested-with-header * https://stackoverflow.com/questions/8163703/cross-domain-ajax-doesnt-send-x-requested-with-header
* *
* In case you are using `fetch()`, pass header manually: * In case you are using `fetch()`, pass header manually:
* *
@ -487,7 +487,13 @@ class Request extends \yii\base\Request
*/ */
public function getIsAjax() public function getIsAjax()
{ {
return $this->headers->get('X-Requested-With') === 'XMLHttpRequest'; $origin = $this->headers->get('Origin');
return
($this->headers->get('X-Requested-With') === 'XMLHttpRequest') ||
($this->headers->get('Sec-Fetch-Mode') === 'cors') ||
($this->headers->get('Sec-Fetch-Site') === 'cross-site') ||
($origin !== null && $origin !== $this->getHostInfo());
} }
/** /**

2
tests/framework/ChangeLogTest.php

@ -18,7 +18,7 @@ class ChangeLogTest extends TestCase
public function changeProvider() public function changeProvider()
{ {
$lines = explode("\n", file_get_contents(__DIR__ . '/../../framework/CHANGELOG.md')); $lines = preg_split("~\R~", file_get_contents(__DIR__ . '/../../framework/CHANGELOG.md'), PREG_SPLIT_NO_EMPTY);
// Don't check last 1500 lines, they are old and often don't obey the standard. // Don't check last 1500 lines, they are old and often don't obey the standard.
$lastIndex = count($lines) - 1500; $lastIndex = count($lines) - 1500;

18
tests/framework/web/RequestTest.php

@ -908,6 +908,24 @@ class RequestTest extends TestCase
], ],
true, true,
], ],
[
[
'HTTP_Sec-Fetch-Mode' => 'cors',
],
true,
],
[
[
'HTTP_Sec-Fetch-Site' => 'cross-site',
],
true,
],
[
[
'HTTP_Origin' => 'https://example.com/',
],
true,
],
]; ];
} }

Loading…
Cancel
Save