PageRenderTime 27ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/cakephp/cakephp/tests/TestCase/Controller/Component/CsrfComponentTest.php

https://gitlab.com/vannh/portal_training
PHP | 308 lines | 170 code | 41 blank | 97 comment | 0 complexity | e470878748a716d36b1759a03cc60bb3 MD5 | raw file
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Controller\Component;
  16. use Cake\Controller\ComponentRegistry;
  17. use Cake\Controller\Component\CsrfComponent;
  18. use Cake\Event\Event;
  19. use Cake\Network\Request;
  20. use Cake\Network\Response;
  21. use Cake\TestSuite\TestCase;
  22. /**
  23. * CsrfComponent test.
  24. */
  25. class CsrfComponentTest extends TestCase
  26. {
  27. /**
  28. * setup
  29. *
  30. * @return void
  31. */
  32. public function setUp()
  33. {
  34. parent::setUp();
  35. $controller = $this->getMock('Cake\Controller\Controller', ['redirect']);
  36. $this->registry = new ComponentRegistry($controller);
  37. $this->component = new CsrfComponent($this->registry);
  38. }
  39. /**
  40. * teardown
  41. *
  42. * @return void
  43. */
  44. public function tearDown()
  45. {
  46. parent::tearDown();
  47. unset($this->component);
  48. }
  49. /**
  50. * Test setting the cookie value
  51. *
  52. * @return void
  53. * @triggers Controller.startup $controller
  54. */
  55. public function testSettingCookie()
  56. {
  57. $_SERVER['REQUEST_METHOD'] = 'GET';
  58. $controller = $this->getMock('Cake\Controller\Controller', ['redirect']);
  59. $controller->request = new Request(['webroot' => '/dir/']);
  60. $controller->response = new Response();
  61. $event = new Event('Controller.startup', $controller);
  62. $this->component->startup($event);
  63. $cookie = $controller->response->cookie('csrfToken');
  64. $this->assertNotEmpty($cookie, 'Should set a token.');
  65. $this->assertRegExp('/^[a-f0-9]+$/', $cookie['value'], 'Should look like a hash.');
  66. $this->assertEquals(0, $cookie['expire'], 'session duration.');
  67. $this->assertEquals('/dir/', $cookie['path'], 'session path.');
  68. $this->assertEquals($cookie['value'], $controller->request->params['_csrfToken']);
  69. }
  70. /**
  71. * Data provider for HTTP method tests.
  72. *
  73. * @return void
  74. */
  75. public static function httpMethodProvider()
  76. {
  77. return [
  78. ['PATCH'], ['PUT'], ['POST'], ['DELETE']
  79. ];
  80. }
  81. /**
  82. * Test that the X-CSRF-Token works with the various http methods.
  83. *
  84. * @dataProvider httpMethodProvider
  85. * @return void
  86. * @triggers Controller.startup $controller
  87. */
  88. public function testValidTokenInHeader($method)
  89. {
  90. $_SERVER['REQUEST_METHOD'] = $method;
  91. $_SERVER['HTTP_X_CSRF_TOKEN'] = 'testing123';
  92. $controller = $this->getMock('Cake\Controller\Controller', ['redirect']);
  93. $controller->request = new Request(['cookies' => ['csrfToken' => 'testing123']]);
  94. $controller->response = new Response();
  95. $event = new Event('Controller.startup', $controller);
  96. $result = $this->component->startup($event);
  97. $this->assertNull($result, 'No exception means valid.');
  98. }
  99. /**
  100. * Test that the X-CSRF-Token works with the various http methods.
  101. *
  102. * @dataProvider httpMethodProvider
  103. * @expectedException \Cake\Network\Exception\ForbiddenException
  104. * @return void
  105. * @triggers Controller.startup $controller
  106. */
  107. public function testInvalidTokenInHeader($method)
  108. {
  109. $_SERVER['REQUEST_METHOD'] = $method;
  110. $_SERVER['HTTP_X_CSRF_TOKEN'] = 'nope';
  111. $controller = $this->getMock('Cake\Controller\Controller', ['redirect']);
  112. $controller->request = new Request([
  113. 'cookies' => ['csrfToken' => 'testing123']
  114. ]);
  115. $controller->response = new Response();
  116. $event = new Event('Controller.startup', $controller);
  117. $this->component->startup($event);
  118. }
  119. /**
  120. * Test that request data works with the various http methods.
  121. *
  122. * @dataProvider httpMethodProvider
  123. * @return void
  124. * @triggers Controller.startup $controller
  125. */
  126. public function testValidTokenRequestData($method)
  127. {
  128. $_SERVER['REQUEST_METHOD'] = $method;
  129. $controller = $this->getMock('Cake\Controller\Controller', ['redirect']);
  130. $controller->request = new Request([
  131. 'post' => ['_csrfToken' => 'testing123'],
  132. 'cookies' => ['csrfToken' => 'testing123']
  133. ]);
  134. $controller->response = new Response();
  135. $event = new Event('Controller.startup', $controller);
  136. $result = $this->component->startup($event);
  137. $this->assertNull($result, 'No exception means valid.');
  138. }
  139. /**
  140. * Test that request data works with the various http methods.
  141. *
  142. * @dataProvider httpMethodProvider
  143. * @expectedException \Cake\Network\Exception\ForbiddenException
  144. * @return void
  145. */
  146. public function testInvalidTokenRequestData($method)
  147. {
  148. $_SERVER['REQUEST_METHOD'] = $method;
  149. $controller = $this->getMock('Cake\Controller\Controller', ['redirect']);
  150. $controller->request = new Request([
  151. 'post' => ['_csrfToken' => 'nope'],
  152. 'cookies' => ['csrfToken' => 'testing123']
  153. ]);
  154. $controller->response = new Response();
  155. $event = new Event('Controller.startup', $controller);
  156. $this->component->startup($event);
  157. }
  158. /**
  159. * Test that missing post field fails
  160. *
  161. * @expectedException \Cake\Network\Exception\ForbiddenException
  162. * @return void
  163. */
  164. public function testInvalidTokenRequestDataMissing()
  165. {
  166. $_SERVER['REQUEST_METHOD'] = 'POST';
  167. $controller = $this->getMock('Cake\Controller\Controller', ['redirect']);
  168. $controller->request = new Request([
  169. 'post' => [],
  170. 'cookies' => ['csrfToken' => 'testing123']
  171. ]);
  172. $controller->response = new Response();
  173. $event = new Event('Controller.startup', $controller);
  174. $this->component->startup($event);
  175. }
  176. /**
  177. * Test that missing header and cookie fails
  178. *
  179. * @dataProvider httpMethodProvider
  180. * @expectedException \Cake\Network\Exception\ForbiddenException
  181. * @return void
  182. */
  183. public function testInvalidTokenMissingCookie($method)
  184. {
  185. $_SERVER['REQUEST_METHOD'] = $method;
  186. $controller = $this->getMock('Cake\Controller\Controller', ['redirect']);
  187. $controller->request = new Request([
  188. 'post' => ['_csrfToken' => 'could-be-valid'],
  189. 'cookies' => []
  190. ]);
  191. $controller->response = new Response();
  192. $event = new Event('Controller.startup', $controller);
  193. $this->component->startup($event);
  194. }
  195. /**
  196. * Test that CSRF checks are not applied to request action requests.
  197. *
  198. * @return void
  199. * @triggers Controller.startup $controller
  200. */
  201. public function testCsrfValidationSkipsRequestAction()
  202. {
  203. $_SERVER['REQUEST_METHOD'] = 'POST';
  204. $controller = $this->getMock('Cake\Controller\Controller', ['redirect']);
  205. $controller->request = new Request([
  206. 'params' => ['requested' => 1],
  207. 'post' => ['_csrfToken' => 'nope'],
  208. 'cookies' => ['csrfToken' => 'testing123']
  209. ]);
  210. $controller->response = new Response();
  211. $event = new Event('Controller.startup', $controller);
  212. $result = $this->component->startup($event);
  213. $this->assertNull($result, 'No error.');
  214. $this->assertEquals('testing123', $controller->request->params['_csrfToken']);
  215. }
  216. /**
  217. * Test that the configuration options work.
  218. *
  219. * @return void
  220. * @triggers Controller.startup $controller
  221. */
  222. public function testConfigurationCookieCreate()
  223. {
  224. $_SERVER['REQUEST_METHOD'] = 'GET';
  225. $controller = $this->getMock('Cake\Controller\Controller', ['redirect']);
  226. $controller->request = new Request(['webroot' => '/dir/']);
  227. $controller->response = new Response();
  228. $component = new CsrfComponent($this->registry, [
  229. 'cookieName' => 'token',
  230. 'expiry' => 90,
  231. 'secure' => true
  232. ]);
  233. $event = new Event('Controller.startup', $controller);
  234. $component->startup($event);
  235. $this->assertEmpty($controller->response->cookie('csrfToken'));
  236. $cookie = $controller->response->cookie('token');
  237. $this->assertNotEmpty($cookie, 'Should set a token.');
  238. $this->assertRegExp('/^[a-f0-9]+$/', $cookie['value'], 'Should look like a hash.');
  239. $this->assertEquals(90, $cookie['expire'], 'session duration.');
  240. $this->assertEquals('/dir/', $cookie['path'], 'session path.');
  241. $this->assertTrue($cookie['secure'], 'cookie security flag missing');
  242. }
  243. /**
  244. * Test that the configuration options work.
  245. *
  246. * @return void
  247. * @triggers Controller.startup $controller
  248. */
  249. public function testConfigurationValidate()
  250. {
  251. $_SERVER['REQUEST_METHOD'] = 'POST';
  252. $controller = $this->getMock('Cake\Controller\Controller', ['redirect']);
  253. $controller->request = new Request([
  254. 'cookies' => ['csrfToken' => 'nope', 'token' => 'yes'],
  255. 'post' => ['_csrfToken' => 'no match', 'token' => 'yes'],
  256. ]);
  257. $controller->response = new Response();
  258. $component = new CsrfComponent($this->registry, [
  259. 'cookieName' => 'token',
  260. 'field' => 'token',
  261. 'expiry' => 90,
  262. ]);
  263. $event = new Event('Controller.startup', $controller);
  264. $result = $component->startup($event);
  265. $this->assertNull($result, 'Config settings should work.');
  266. }
  267. }