ソースを参照

Merge pull request #13776 from CakeDC/issue/13767

refs #13767 don't set csrf cookie on redirect
ADmad 6 年 前
コミット
33f9c78dff

+ 5 - 1
src/Http/Middleware/CsrfProtectionMiddleware.php

@@ -27,6 +27,7 @@ use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use Psr\Http\Server\MiddlewareInterface;
 use Psr\Http\Server\RequestHandlerInterface;
+use Zend\Diactoros\Response\RedirectResponse;
 
 /**
  * Provides CSRF protection & validation.
@@ -119,8 +120,11 @@ class CsrfProtectionMiddleware implements MiddlewareInterface
         if ($method === 'GET' && $cookieData === null) {
             $token = $this->_createToken();
             $request = $request->withAttribute('csrfToken', $token);
-            /** @var \Cake\Http\Response $response */
+            /** @var mixed $response */
             $response = $handler->handle($request);
+            if ($response instanceof RedirectResponse) {
+                return $response;
+            }
 
             return $this->_addTokenCookie($token, $request, $response);
         }

+ 26 - 0
tests/TestCase/Http/Middleware/CsrfProtectionMiddlewareTest.php

@@ -22,6 +22,7 @@ use Cake\Http\ServerRequest;
 use Cake\TestSuite\TestCase;
 use Psr\Http\Message\ServerRequestInterface;
 use TestApp\Http\TestRequestHandler;
+use Zend\Diactoros\Response\RedirectResponse;
 
 /**
  * Test for CsrfProtection
@@ -120,6 +121,31 @@ class CsrfProtectionMiddlewareTest extends TestCase
     }
 
     /**
+     * Test that the CSRF tokens are not set for redirect responses
+     *
+     * @return void
+     */
+    public function testRedirectResponseCookiesNotSet()
+    {
+        $request = new ServerRequest([
+            'environment' => ['REQUEST_METHOD' => 'GET'],
+        ]);
+        $expectedResponse = new RedirectResponse('/');
+        $handler = new TestRequestHandler(function ($request) use ($expectedResponse) {
+
+            return $expectedResponse;
+        });
+
+        $middleware = $this->getMockBuilder(CsrfProtectionMiddleware::class)
+            ->onlyMethods(['_addTokenCookie'])
+            ->getMock();
+        $middleware->expects($this->never())
+            ->method('_addTokenCookie');
+        $response = $middleware->process($request, $handler);
+        $this->assertSame($expectedResponse, $response);
+    }
+
+    /**
      * Test that the X-CSRF-Token works with the various http methods.
      *
      * @dataProvider httpMethodProvider