PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/codeigniter/core/Security_test.php

https://gitlab.com/project-store/CodeIgniter
PHP | 335 lines | 219 code | 81 blank | 35 comment | 1 complexity | cfa887db004bf372dba46581a4f570b8 MD5 | raw file
  1. <?php
  2. class Security_test extends CI_TestCase {
  3. public function set_up()
  4. {
  5. // Set cookie for security test
  6. $_COOKIE['ci_csrf_cookie'] = md5(uniqid(mt_rand(), TRUE));
  7. // Set config for Security class
  8. $this->ci_set_config('csrf_protection', TRUE);
  9. $this->ci_set_config('csrf_token_name', 'ci_csrf_token');
  10. $this->ci_set_config('csrf_cookie_name', 'ci_csrf_cookie');
  11. $this->security = new Mock_Core_Security();
  12. }
  13. // --------------------------------------------------------------------
  14. public function test_csrf_verify()
  15. {
  16. $_SERVER['REQUEST_METHOD'] = 'GET';
  17. $this->assertInstanceOf('CI_Security', $this->security->csrf_verify());
  18. }
  19. // --------------------------------------------------------------------
  20. public function test_csrf_verify_invalid()
  21. {
  22. // Without issuing $_POST[csrf_token_name], this request will triggering CSRF error
  23. $_SERVER['REQUEST_METHOD'] = 'POST';
  24. $this->setExpectedException('RuntimeException', 'CI Error: The action you have requested is not allowed');
  25. $this->security->csrf_verify();
  26. }
  27. // --------------------------------------------------------------------
  28. public function test_csrf_verify_valid()
  29. {
  30. $_SERVER['REQUEST_METHOD'] = 'POST';
  31. $_POST[$this->security->csrf_token_name] = $this->security->csrf_hash;
  32. $this->assertInstanceOf('CI_Security', $this->security->csrf_verify());
  33. }
  34. // --------------------------------------------------------------------
  35. public function test_get_csrf_hash()
  36. {
  37. $this->assertEquals($this->security->csrf_hash, $this->security->get_csrf_hash());
  38. }
  39. // --------------------------------------------------------------------
  40. public function test_get_csrf_token_name()
  41. {
  42. $this->assertEquals('ci_csrf_token', $this->security->get_csrf_token_name());
  43. }
  44. // --------------------------------------------------------------------
  45. public function test_xss_clean()
  46. {
  47. $harm_string = "Hello, i try to <script>alert('Hack');</script> your site";
  48. $harmless_string = $this->security->xss_clean($harm_string);
  49. $this->assertEquals("Hello, i try to [removed]alert&#40;'Hack'&#41;;[removed] your site", $harmless_string);
  50. }
  51. // --------------------------------------------------------------------
  52. public function test_xss_clean_string_array()
  53. {
  54. $harm_strings = array(
  55. "Hello, i try to <script>alert('Hack');</script> your site",
  56. "Simple clean string",
  57. "Hello, i try to <script>alert('Hack');</script> your site"
  58. );
  59. $harmless_strings = $this->security->xss_clean($harm_strings);
  60. $this->assertEquals("Hello, i try to [removed]alert&#40;'Hack'&#41;;[removed] your site", $harmless_strings[0]);
  61. $this->assertEquals("Simple clean string", $harmless_strings[1]);
  62. $this->assertEquals("Hello, i try to [removed]alert&#40;'Hack'&#41;;[removed] your site", $harmless_strings[2]);
  63. }
  64. // --------------------------------------------------------------------
  65. public function test_xss_clean_image_valid()
  66. {
  67. $harm_string = '<img src="test.png">';
  68. $xss_clean_return = $this->security->xss_clean($harm_string, TRUE);
  69. // $this->assertTrue($xss_clean_return);
  70. }
  71. // --------------------------------------------------------------------
  72. public function test_xss_clean_image_invalid()
  73. {
  74. $harm_string = '<img src=javascript:alert(String.fromCharCode(88,83,83))>';
  75. $xss_clean_return = $this->security->xss_clean($harm_string, TRUE);
  76. $this->assertFalse($xss_clean_return);
  77. }
  78. // --------------------------------------------------------------------
  79. public function test_xss_clean_entity_double_encoded()
  80. {
  81. $input = '<a href="&#38&#35&#49&#48&#54&#38&#35&#57&#55&#38&#35&#49&#49&#56&#38&#35&#57&#55&#38&#35&#49&#49&#53&#38&#35&#57&#57&#38&#35&#49&#49&#52&#38&#35&#49&#48&#53&#38&#35&#49&#49&#50&#38&#35&#49&#49&#54&#38&#35&#53&#56&#38&#35&#57&#57&#38&#35&#49&#49&#49&#38&#35&#49&#49&#48&#38&#35&#49&#48&#50&#38&#35&#49&#48&#53&#38&#35&#49&#49&#52&#38&#35&#49&#48&#57&#38&#35&#52&#48&#38&#35&#52&#57&#38&#35&#52&#49">Clickhere</a>';
  82. $this->assertEquals('<a >Clickhere</a>', $this->security->xss_clean($input));
  83. }
  84. // --------------------------------------------------------------------
  85. public function text_xss_clean_js_link_removal()
  86. {
  87. // This one is to prevent a false positive
  88. $this->assertEquals(
  89. "<a href=\"javascrip\n<t\n:alert\n&#40;1&#41;\"\n>",
  90. $this->security->xss_clean("<a href=\"javascrip\n<t\n:alert\n(1)\"\n>")
  91. );
  92. }
  93. // --------------------------------------------------------------------
  94. public function test_xss_clean_js_img_removal()
  95. {
  96. $input = '<img src="&#38&#35&#49&#48&#54&#38&#35&#57&#55&#38&#35&#49&#49&#56&#38&#35&#57&#55&#38&#35&#49&#49&#53&#38&#35&#57&#57&#38&#35&#49&#49&#52&#38&#35&#49&#48&#53&#38&#35&#49&#49&#50&#38&#35&#49&#49&#54&#38&#35&#53&#56&#38&#35&#57&#57&#38&#35&#49&#49&#49&#38&#35&#49&#49&#48&#38&#35&#49&#48&#50&#38&#35&#49&#48&#53&#38&#35&#49&#49&#52&#38&#35&#49&#48&#57&#38&#35&#52&#48&#38&#35&#52&#57&#38&#35&#52&#49">Clickhere';
  97. $this->assertEquals('<img >', $this->security->xss_clean($input));
  98. }
  99. // --------------------------------------------------------------------
  100. public function test_xss_clean_sanitize_naughty_html_tags()
  101. {
  102. $this->assertEquals('&lt;unclosedTag', $this->security->xss_clean('<unclosedTag'));
  103. $this->assertEquals('&lt;blink&gt;', $this->security->xss_clean('<blink>'));
  104. $this->assertEquals('<fubar>', $this->security->xss_clean('<fubar>'));
  105. $this->assertEquals(
  106. '<img [removed]> src="x">',
  107. $this->security->xss_clean('<img <svg=""> src="x">')
  108. );
  109. $this->assertEquals(
  110. '<img src="b on=">on=">"x onerror="alert&#40;1&#41;">',
  111. $this->security->xss_clean('<img src="b on="<x">on=">"x onerror="alert(1)">')
  112. );
  113. }
  114. // --------------------------------------------------------------------
  115. public function test_xss_clean_sanitize_naughty_html_attributes()
  116. {
  117. $this->assertEquals('<foo [removed]>', $this->security->xss_clean('<foo onAttribute="bar">'));
  118. $this->assertEquals('<foo [removed]>', $this->security->xss_clean('<foo onAttributeNoQuotes=bar>'));
  119. $this->assertEquals('<foo [removed]bar>', $this->security->xss_clean('<foo onAttributeWithSpaces = bar>'));
  120. $this->assertEquals('<foo prefixOnAttribute="bar">', $this->security->xss_clean('<foo prefixOnAttribute="bar">'));
  121. $this->assertEquals('<foo>onOutsideOfTag=test</foo>', $this->security->xss_clean('<foo>onOutsideOfTag=test</foo>'));
  122. $this->assertEquals('onNoTagAtAll = true', $this->security->xss_clean('onNoTagAtAll = true'));
  123. $this->assertEquals('<foo [removed]>', $this->security->xss_clean('<foo fscommand=case-insensitive>'));
  124. $this->assertEquals('<foo [removed]>', $this->security->xss_clean('<foo seekSegmentTime=whatever>'));
  125. $this->assertEquals(
  126. '<foo bar=">" baz=\'>\' [removed]>',
  127. $this->security->xss_clean('<foo bar=">" baz=\'>\' onAfterGreaterThan="quotes">')
  128. );
  129. $this->assertEquals(
  130. '<foo bar=">" baz=\'>\' [removed]>',
  131. $this->security->xss_clean('<foo bar=">" baz=\'>\' onAfterGreaterThan=noQuotes>')
  132. );
  133. $this->assertEquals(
  134. '<img src="x" on=""> on=&lt;svg&gt; onerror=alert&#40;1&#41;>',
  135. $this->security->xss_clean('<img src="x" on=""> on=<svg> onerror=alert(1)>')
  136. );
  137. $this->assertEquals(
  138. '<img src="on=\'">"&lt;svg&gt; onerror=alert&#40;1&#41; onmouseover=alert&#40;1&#41;>',
  139. $this->security->xss_clean('<img src="on=\'">"<svg> onerror=alert(1) onmouseover=alert(1)>')
  140. );
  141. $this->assertEquals(
  142. '<img src="x"> on=\'x\' onerror=``,alert&#40;1&#41;>',
  143. $this->security->xss_clean('<img src="x"> on=\'x\' onerror=``,alert(1)>')
  144. );
  145. $this->assertEquals(
  146. '<a [removed]>',
  147. $this->security->xss_clean('<a< onmouseover="alert(1)">')
  148. );
  149. $this->assertEquals(
  150. '<img src="x"> on=\'x\' onerror=,xssm()>',
  151. $this->security->xss_clean('<img src="x"> on=\'x\' onerror=,xssm()>')
  152. );
  153. $this->assertEquals(
  154. '<image src="<>" [removed]>',
  155. $this->security->xss_clean('<image src="<>" onerror=\'alert(1)\'>')
  156. );
  157. $this->assertEquals(
  158. '<b [removed] [removed]>',
  159. $this->security->xss_clean('<b "=<= onmouseover=alert(1)>')
  160. );
  161. $this->assertEquals(
  162. '<b [removed] [removed]alert&#40;1&#41;,1>1">',
  163. $this->security->xss_clean('<b a=<=" onmouseover="alert(1),1>1">')
  164. );
  165. }
  166. // --------------------------------------------------------------------
  167. /**
  168. * @depends test_xss_clean_sanitize_naughty_html_tags
  169. * @depends test_xss_clean_sanitize_naughty_html_attributes
  170. */
  171. public function test_naughty_html_plus_evil_attributes()
  172. {
  173. $this->assertEquals(
  174. '&lt;svg<img &gt; src="x" [removed]>',
  175. $this->security->xss_clean('<svg<img > src="x" onerror="location=/javascript/.source+/:alert/.source+/(1)/.source">')
  176. );
  177. }
  178. // --------------------------------------------------------------------
  179. public function test_xss_hash()
  180. {
  181. $this->assertEmpty($this->security->xss_hash);
  182. // Perform hash
  183. $this->security->xss_hash();
  184. $this->assertTrue(preg_match('#^[0-9a-f]{32}$#iS', $this->security->xss_hash) === 1);
  185. }
  186. // --------------------------------------------------------------------
  187. public function test_get_random_bytes()
  188. {
  189. $length = "invalid";
  190. $this->assertFalse($this->security->get_random_bytes($length));
  191. $length = 10;
  192. $this->assertNotEmpty($this->security->get_random_bytes($length));
  193. }
  194. // --------------------------------------------------------------------
  195. public function test_entity_decode()
  196. {
  197. $encoded = '&lt;div&gt;Hello &lt;b&gt;Booya&lt;/b&gt;&lt;/div&gt;';
  198. $decoded = $this->security->entity_decode($encoded);
  199. $this->assertEquals('<div>Hello <b>Booya</b></div>', $decoded);
  200. // Issue #3057 (https://github.com/bcit-ci/CodeIgniter/issues/3057)
  201. $this->assertEquals(
  202. '&foo should not include a semicolon',
  203. $this->security->entity_decode('&foo should not include a semicolon')
  204. );
  205. }
  206. // --------------------------------------------------------------------
  207. public function test_sanitize_filename()
  208. {
  209. $filename = './<!--foo-->';
  210. $safe_filename = $this->security->sanitize_filename($filename);
  211. $this->assertEquals('foo', $safe_filename);
  212. }
  213. // --------------------------------------------------------------------
  214. public function test_strip_image_tags()
  215. {
  216. $imgtags = array(
  217. '<img src="smiley.gif" alt="Smiley face" height="42" width="42">',
  218. '<img alt="Smiley face" height="42" width="42" src="smiley.gif">',
  219. '<img src="http://www.w3schools.com/images/w3schools_green.jpg">',
  220. '<img src="/img/sunset.gif" height="100%" width="100%">',
  221. '<img src="mdn-logo-sm.png" alt="MD Logo" srcset="mdn-logo-HD.png 2x, mdn-logo-small.png 15w, mdn-banner-HD.png 100w 2x" />',
  222. '<img sqrc="/img/sunset.gif" height="100%" width="100%">',
  223. '<img srqc="/img/sunset.gif" height="100%" width="100%">',
  224. '<img srcq="/img/sunset.gif" height="100%" width="100%">'
  225. );
  226. $urls = array(
  227. 'smiley.gif',
  228. 'smiley.gif',
  229. 'http://www.w3schools.com/images/w3schools_green.jpg',
  230. '/img/sunset.gif',
  231. 'mdn-logo-sm.png',
  232. '<img sqrc="/img/sunset.gif" height="100%" width="100%">',
  233. '<img srqc="/img/sunset.gif" height="100%" width="100%">',
  234. '<img srcq="/img/sunset.gif" height="100%" width="100%">'
  235. );
  236. for ($i = 0; $i < count($imgtags); $i++)
  237. {
  238. $this->assertEquals($urls[$i], $this->security->strip_image_tags($imgtags[$i]));
  239. }
  240. }
  241. // --------------------------------------------------------------------
  242. public function test_csrf_set_hash()
  243. {
  244. // Set cookie for security test
  245. $_COOKIE['ci_csrf_cookie'] = md5(uniqid(mt_rand(), TRUE));
  246. // Set config for Security class
  247. $this->ci_set_config('csrf_protection', TRUE);
  248. $this->ci_set_config('csrf_token_name', 'ci_csrf_token');
  249. // leave csrf_cookie_name as blank to test _csrf_set_hash function
  250. $this->ci_set_config('csrf_cookie_name', '');
  251. $this->security = new Mock_Core_Security();
  252. $this->assertNotEmpty($this->security->get_csrf_hash());
  253. }
  254. }