diff --git a/html/main.php b/html/main.php
index 856a64e6bc97dacbb263c7d086c997db46597529..1d03fbac5a31278d610d6027dddb3ff39cc13bf1 100644
--- a/html/main.php
+++ b/html/main.php
@@ -1,9 +1,8 @@
 <?php
-
 /*
   This code is part of FusionDirectory (http://www.fusiondirectory.org/)
   Copyright (C) 2003-2010  Cajus Pollmeier
-  Copyright (C) 2011-2016  FusionDirectory
+  Copyright (C) 2011-2018  FusionDirectory
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -54,6 +53,8 @@ if (!session::global_is_set('connected')) {
   exit;
 }
 
+CSRFProtection::check();
+
 $ui     = session::global_get('ui');
 $config = session::global_get('config');
 
@@ -324,7 +325,8 @@ if (session::is_set('errors') && session::get('errors') != "") {
 $focus = '<script type="text/javascript">';
 $focus .= 'next_msg_dialog();';
 $focus .= '</script>';
-$smarty->assign("focus", $focus);
+$smarty->assign('focus',      $focus);
+$smarty->assign('CSRFtoken',  CSRFProtection::getToken());
 
 /* Set channel if needed */
 //TODO: * move all global session calls to global_
diff --git a/html/setup.php b/html/setup.php
index 6c77f663c1bb307f367a83e07f6cdd6fa990bb02..70378bb11405d566f59b73b62813ab83318f46b2 100644
--- a/html/setup.php
+++ b/html/setup.php
@@ -49,6 +49,8 @@ session::start();
 session::global_set('DEBUGLEVEL', 0);
 session::set('errorsAlreadyPosted', array());
 
+CSRFProtection::check();
+
 /* Attribute initialization, reset errors */
 reset_errors();
 
@@ -124,6 +126,7 @@ $smarty->assign("navigation",     $setup->get_navigation_html());
 $smarty->assign("headline_image", $setup->get_header_image());
 $smarty->assign("headline",       $setup->get_header_text());
 $smarty->assign("focus",          $focus);
+$smarty->assign('CSRFtoken',      CSRFProtection::getToken());
 $smarty->assign("msg_dialogs",    msg_dialog::get_dialogs());
 
 if ($error_collector != "") {
diff --git a/ihtml/themes/breezy/framework.tpl b/ihtml/themes/breezy/framework.tpl
index d1061fe2821622203d72f5cd9a4e8a4f95ec1a95..ba6b98d155fff9cd70cbf57049f9705644410e85 100644
--- a/ihtml/themes/breezy/framework.tpl
+++ b/ihtml/themes/breezy/framework.tpl
@@ -55,6 +55,7 @@
     {$errors}
     {$focus}
     <input type="hidden" name="php_c_check" value="1"/>
+    <input type="hidden" name="CSRFtoken" value="{$CSRFtoken}"/>
   </form>
 
 
diff --git a/include/class_CSRFProtection.inc b/include/class_CSRFProtection.inc
new file mode 100644
index 0000000000000000000000000000000000000000..a2d8148889e33f720c0aeec3a188e0c898a7f6ac
--- /dev/null
+++ b/include/class_CSRFProtection.inc
@@ -0,0 +1,69 @@
+<?php
+/*
+  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
+  Copyright (C) 2017-2018 FusionDirectory
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+class CSRFProtection
+{
+  public static function check()
+  {
+    if (empty($_POST)) {
+      return;
+    }
+    if (empty($_POST['CSRFtoken'])) {
+      throw new FusionDirectoryException('CSRF protection token missing');
+    }
+
+    static::checkHeaders();
+
+    if ($_POST['CSRFtoken'] !== static::getToken()) {
+      throw new FusionDirectoryException('CSRF protection token invalid');
+    }
+  }
+
+  public static function getToken()
+  {
+    if (!session::is_set('CSRFtoken')) {
+      session::set('CSRFtoken', standAlonePage::generateRandomHash());
+    }
+    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 && !hash_equals($origin, $target)) {
+        throw new FusionDirectoryException('CSRF detected: origin and target are not matching ('.$origin.' != '.$target.')');
+      }
+    }
+  }
+}
diff --git a/setup/setup_frame.tpl b/setup/setup_frame.tpl
index 071f5365c7636c16143a1b124394f27cb7a7bd75..03dd16c5076b26a1e9a6be823a8c540a602b61a7 100644
--- a/setup/setup_frame.tpl
+++ b/setup/setup_frame.tpl
@@ -39,6 +39,7 @@
     {$errors}
     {$focus}
     <input type="hidden" name="setup_goto_step" value=""/>
+    <input type="hidden" name="CSRFtoken" value="{$CSRFtoken}"/>
   </form>
 
 </body>