SproutCMS

This is the code documentation for the SproutCMS project

source of /sprout/Helpers/Csrf.php

  1. <?php
  2. /*
  3.  * Copyright (C) 2017 Karmabunny Pty Ltd.
  4.  *
  5.  * This file is a part of SproutCMS.
  6.  *
  7.  * SproutCMS is free software: you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation, either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * For more information, visit <http://getsproutcms.com>.
  12.  */
  13.  
  14. namespace Sprout\Helpers;
  15.  
  16.  
  17. /**
  18.  * Protection against Cross Site Request Forgery (CSRF) attacks
  19.  */
  20. class Csrf
  21. {
  22. /**
  23.   * Initialises the PHP session and, if not present, generates a CSRF secret for the session
  24.   *
  25.   * @return void
  26.   */
  27. protected static function initialiseSession()
  28. {
  29. Session::instance();
  30.  
  31. if (!isset($_SESSION['csrf_token'])) {
  32. $_SESSION['csrf_token'] = Security::randStr(32);
  33. }
  34. }
  35.  
  36. /**
  37.   * Generates a CSRF hidden form field
  38.   *
  39.   * @return string HTML: an <input type="hidden"> tag which contains the token
  40.   */
  41. public static function token()
  42. {
  43. self::initialiseSession();
  44.  
  45. return '<input type="hidden" name="edit_token" value="' . Enc::html($_SESSION['csrf_token']) . '">';
  46. }
  47.  
  48.  
  49. /**
  50.   * Gets the CSRF token in the postdata.
  51.   * Checks that it is valid.
  52.   * Returns TRUE on success and FALSE on failure
  53.   **/
  54. public static function check()
  55. {
  56. Session::instance();
  57.  
  58. // Clearly invalid request, avoid any exceptions being generated
  59. if (empty($_POST['edit_token']) or empty($_SESSION['csrf_token'])) {
  60. return false;
  61. }
  62.  
  63. if ($_POST['edit_token'] !== $_SESSION['csrf_token']) {
  64. return false;
  65. }
  66.  
  67. return true;
  68. }
  69.  
  70.  
  71. /**
  72.   * Checks the CSRF token
  73.   * If it fails, redirect the user to the home page, and report an error
  74.   **/
  75. public static function checkOrDie()
  76. {
  77. if (self::check()) return;
  78.  
  79. Notification::error('Session timeout or missing security token');
  80. Url::redirect('result/error');
  81. }
  82.  
  83.  
  84. /**
  85.   * Fetches the secret token value
  86.   *
  87.   * This is intended for use on JavaScript requests that require CSRF protection.
  88.   * Note that it is important that this value isn't placed in GET parameters, as this
  89.   * may result in the value being leaked through logging or other methods.
  90.   *
  91.   * @return string The CSRF secret
  92.   */
  93. public static function getTokenValue()
  94. {
  95. self::initialiseSession();
  96.  
  97. return $_SESSION['csrf_token'];
  98. }
  99. }
  100.  
  101.  
  102.