From 6e31f4861930c83e41fd1566d312e078b1f47ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= <come@opensides.be> Date: Mon, 4 Jun 2018 16:42:44 +0200 Subject: [PATCH] :sparkles: feat(core) Reject CSRF based on HEADER values issue #5840 --- include/class_CSRFProtection.inc | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/include/class_CSRFProtection.inc b/include/class_CSRFProtection.inc index 3c6992ab5..7c3f6954a 100644 --- a/include/class_CSRFProtection.inc +++ b/include/class_CSRFProtection.inc @@ -29,6 +29,8 @@ class CSRFProtection throw new Exception('CSRF protection token missing'); } + static::checkHeaders(); + $validToken = static::getToken(); if ($_POST['CSRFtoken'] !== static::getToken()) { throw new Exception('CSRF protection token invalid'); @@ -42,4 +44,29 @@ class CSRFProtection } return session::get('CSRFtoken'); } + + public static function checkHeaders() + { + $origin = FALSE; + if (!empty($_SERVER['HTTP_ORIGIN'])) { + $origin = $_SERVER['HTTP_ORIGIN']; + } elseif (!empty($_SERVER['HTTP_REFERER'])) { + $origin = $_SERVER['HTTP_REFERER']; + } + if ($origin) { + $origin = preg_replace('|^[^/]+://([^/]+)(/.*)?$|', '\1', $origin); + $target = FALSE; + if (!empty($_SERVER['HTTP_X_FORWARDED_HOST'])) { + $target = $_SERVER['HTTP_X_FORWARDED_HOST']; + } else + if (!empty($_SERVER['HTTP_HOST'])) { + $target = $_SERVER['HTTP_HOST']; + } + if ($target) { + if (!hash_equals($origin, $target)) { + throw new Exception('CSRF detected: origin and target are not matching ('.$origin.' != '.$target.')'); + } + } + } + } } -- GitLab