lollhosh

secure call ajax

Apr 6th, 2020
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.47 KB | None | 0 0
  1.  
  2. +50
  3.  
  4. 1. Check the ORIGIN header
  5.  
  6. As specified by OWASP, this is not enough but recommended :
  7.  
  8. Although it is trivial to spoof any header from your own browser, it is generally impossible to do so in a CSRF attack, except via an XSS vulnerability. That's why checking headers is a reasonable first step in your CSRF defense, but since they aren't always present, its generally not considered a sufficient defense on its own.
  9.  
  10. And by Mozilla :
  11.  
  12. The Origin header is considered helpful against JSON data theft and CSRF attacks. The information provided by Origin--a bit of contextual request-creation information--should provide hints to web servers about trustworthiness of requests [...]
  13.  
  14. Checking the HTTP_ORIGIN header could be written as :
  15.  
  16. header('Content-Type: application/json');
  17.  
  18. if (isset($_SERVER['HTTP_ORIGIN'])) {
  19. $address = 'http://' . $_SERVER['SERVER_NAME'];
  20. if (strpos($address, $_SERVER['HTTP_ORIGIN']) !== 0) {
  21. exit(json_encode([
  22. 'error' => 'Invalid Origin header: ' . $_SERVER['HTTP_ORIGIN']
  23. ]));
  24. }
  25. } else {
  26. exit(json_encode(['error' => 'No Origin header']));
  27. }
  28.  
  29. 1. (bis) Check the REFERER header
  30.  
  31. Again from OWASP :
  32.  
  33. If the Origin header is not present, verify the hostname in the Referer header matches the site's origin. Checking the referer is a commonly used method of preventing CSRF on embedded network devices because it does not require a per-user state.. This method of CSRF mitigation is also commonly used with unauthenticated requests [...]
  34.  
  35. Checking the HTTP_REFERER is also quite simple in PHP with $_SERVER['HTTP_REFERER'], you can just update the above code with it.
  36.  
  37. BE CAREFUL with the checking which always need to be really specific : do no check just example.com or api.example.com but the full https://example.com. Why ? Because you could spoof this check with an origin like api.example.com.hacker.com.
  38.  
  39. 2. Generate CSRF tokens
  40.  
  41. A well-explained answer specific to PHP has been given there, in short :
  42.  
  43. Generate the token :
  44.  
  45. session_start();
  46. if (empty($_SESSION['csrf_token'])) {
  47. $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
  48. }
  49.  
  50. Add it in your generated views via a meta (like Github) :
  51.  
  52. <meta name="csrf-token" content="<?= $_SESSION['csrf_token'] ?>">
  53.  
  54. Setup jQuery ajax calls to include this token :
  55.  
  56. $.ajaxSetup({
  57. headers : {
  58. 'CsrfToken': $('meta[name="csrf-token"]').attr('content')
  59. }
  60. });
  61.  
  62. Server-side check your AJAX requests :
  63.  
  64. session_start();
  65. if (empty($_SESSION['csrf_token'])) {
  66. $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
  67. }
  68.  
  69. header('Content-Type: application/json');
  70.  
  71. $headers = apache_request_headers();
  72. if (isset($headers['CsrfToken'])) {
  73. if ($headers['CsrfToken'] !== $_SESSION['csrf_token']) {
  74. exit(json_encode(['error' => 'Wrong CSRF token.']));
  75. }
  76. } else {
  77. exit(json_encode(['error' => 'No CSRF token.']));
  78. }
  79.  
  80. Most PHP frameworks have their own CSRF implementation, which more or less lay upon the same principle.
  81.  
  82. 3. Sanitize validate user input.
  83.  
  84. You always must filter espace inputs and validate them.
  85.  
  86. 4. Protect your server
  87.  
  88. Limit the number of your requests.
  89. Use https as much as possible.
  90. Block bad queries.
  91. Protect POST requests.
  92.  
  93. 5. Never trust user input
  94.  
  95. As @blue112 said, it is one of the most elementary security principles.
  96.  
  97. enter image description here
  98. shareimprove this answer
  99. edited May 23 '17 at 12:02
  100. Community♦
  101. 111 silver badge
  102. answered Jun 19 '16 at 23:47
  103. Ivan Gabriele
  104. 4,32822 gold badges2828 silver badges4949 bronze badges
  105.  
  106. 1
  107. X-Requested-With is a non-standard header which never tells you what URL initiated the request. That's Origin, which is easily forged if the attacker isn't doing a CSRF attack. – Quentin Jun 21 '16 at 23:48
  108. I had to change the session array key to "Csrf-Token", otherwise it got renamed on my server to "Csrftoken" in the apache headers. – Dennis Heiden May 23 '17 at 16:37
  109. is it secure enough to use openssl_random_pseudo_bytes() for generating random bytes? – wpcoder Oct 25 '17 at 19:16
  110. 1
  111. @wpcoder I'm not an expert in cryptographic security. However the PHP official documentation and some googling tells me that "pseudo-random" is less random than "cryptographic random". Moreover, Symfony and Laravel (based on Foundation) are also both using random_bytes. – Ivan Gabriele Oct
Add Comment
Please, Sign In to add comment