prevent_csrf.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. $check_csrf = true;
  3. if (
  4. $_SERVER["SCRIPT_FILENAME"] == "/usr/local/hestia/web/inc/mail-wrapper.php" ||
  5. $_SERVER["SCRIPT_FILENAME"] == "/usr/local/hestia//web/inc/mail-wrapper.php"
  6. ) {
  7. $check_csrf = false;
  8. } // execute only from CLI
  9. if (
  10. $_SERVER["SCRIPT_FILENAME"] == "/usr/local/hestia/web/reset/mail/index.php" ||
  11. $_SERVER["SCRIPT_FILENAME"] == "/usr/local/hestia/web//reset/mail/index.php"
  12. ) {
  13. $check_csrf = false;
  14. } // Localhost only
  15. if (
  16. $_SERVER["SCRIPT_FILENAME"] == "/usr/local/hestia/web/api/index.php" ||
  17. $_SERVER["SCRIPT_FILENAME"] == "/usr/local/hestia/web//api/index.php"
  18. ) {
  19. $check_csrf = false;
  20. } // Own check
  21. if (substr($_SERVER["SCRIPT_FILENAME"], 0, 22) == "/usr/local/hestia/bin/") {
  22. $check_csrf = false;
  23. }
  24. function checkStrictness($level) {
  25. if ($level >= $_SESSION["POLICY_CSRF_STRICTNESS"]) {
  26. return true;
  27. } else {
  28. http_response_code(400);
  29. echo "<h1>Potential CSRF use detected</h1>\n" .
  30. "<p>Please disable any plugins/add-ons inside your browser or contact your system administrator. If you are the system administrator you can run v-change-sys-config-value 'POLICY_CSRF_STRICTNESS' '0' as root to disable this check.<p>" .
  31. "<p>If you followed a bookmark or an static link please <a href='/'>navigate to root</a>";
  32. die();
  33. }
  34. }
  35. function prevent_post_csrf() {
  36. if (!empty($_SERVER["REQUEST_METHOD"])) {
  37. if ($_SERVER["REQUEST_METHOD"] === "POST") {
  38. if (!empty($_SERVER["HTTP_HOST"])) {
  39. $hostname = preg_replace(
  40. "/(\[?[^]]*\]?):([0-9]{1,5})$/",
  41. "$1",
  42. $_SERVER["HTTP_HOST"],
  43. );
  44. $port_is_defined = preg_match("/\[?[^]]*\]?:[0-9]{1,5}$/", $_SERVER["HTTP_HOST"]);
  45. if ($port_is_defined) {
  46. $port = preg_replace(
  47. "/(\[?[^]]*\]?):([0-9]{1,5})$/",
  48. "$2",
  49. $_SERVER["HTTP_HOST"],
  50. );
  51. } else {
  52. $port = 443;
  53. }
  54. } else {
  55. $hostname = gethostname();
  56. $port = 443;
  57. }
  58. if (isset($_SERVER["HTTP_ORIGIN"])) {
  59. $origin_host = parse_url($_SERVER["HTTP_ORIGIN"], PHP_URL_HOST);
  60. if (
  61. strcmp($origin_host, gethostname()) === 0 &&
  62. in_array($port, ["443", $_SERVER["SERVER_PORT"]])
  63. ) {
  64. return checkStrictness(2);
  65. } else {
  66. if (
  67. strcmp($origin_host, $hostname) === 0 &&
  68. in_array($port, ["443", $_SERVER["SERVER_PORT"]])
  69. ) {
  70. return checkStrictness(1);
  71. } else {
  72. return checkStrictness(0);
  73. }
  74. }
  75. }
  76. }
  77. }
  78. }
  79. function prevent_get_csrf() {
  80. if (!empty($_SERVER["REQUEST_METHOD"])) {
  81. if ($_SERVER["REQUEST_METHOD"] === "GET") {
  82. if (!empty($_SERVER["HTTP_HOST"])) {
  83. $hostname = preg_replace(
  84. "/(\[?[^]]*\]?):([0-9]{1,5})$/",
  85. "$1",
  86. $_SERVER["HTTP_HOST"],
  87. );
  88. $port_is_defined = preg_match("/\[?[^]]*\]?:[0-9]{1,5}$/", $_SERVER["HTTP_HOST"]);
  89. if ($port_is_defined) {
  90. $port = preg_replace(
  91. "/(\[?[^]]*\]?):([0-9]{1,5})$/",
  92. "$2",
  93. $_SERVER["HTTP_HOST"],
  94. );
  95. } else {
  96. $port = 443;
  97. }
  98. } else {
  99. $hostname = gethostname();
  100. $port = 443;
  101. }
  102. //list of possible entries route and these should never be blocked
  103. if (
  104. in_array($_SERVER["DOCUMENT_URI"], [
  105. "/list/user/index.php",
  106. "/login/index.php",
  107. "/list/web/index.php",
  108. "/list/dns/index.php",
  109. "/list/mail/index.php",
  110. "/list/db/index.php",
  111. "/list/cron/index.php",
  112. "/list/backup/index.php",
  113. "/reset/index.php",
  114. ])
  115. ) {
  116. return true;
  117. }
  118. if (isset($_SERVER["HTTP_REFERER"])) {
  119. $referrer_host = parse_url($_SERVER["HTTP_REFERER"], PHP_URL_HOST);
  120. if (
  121. strcmp($referrer_host, gethostname()) === 0 &&
  122. in_array($port, ["443", $_SERVER["SERVER_PORT"]])
  123. ) {
  124. return checkStrictness(2);
  125. } else {
  126. if (
  127. strcmp($referrer_host, $hostname) === 0 &&
  128. in_array($port, ["443", $_SERVER["SERVER_PORT"]])
  129. ) {
  130. return checkStrictness(1);
  131. } else {
  132. return checkStrictness(0);
  133. }
  134. }
  135. } else {
  136. return checkStrictness(0);
  137. }
  138. }
  139. }
  140. }
  141. if ($check_csrf == true) {
  142. prevent_post_csrf();
  143. prevent_get_csrf();
  144. }