diff --git a/common b/common
index 3dfc2b71eb6a7e0746fe8794854f739c3305587b..c7eac74cf1f7e03b06f255cfd01e54162a2b9631 160000
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit 3dfc2b71eb6a7e0746fe8794854f739c3305587b
+Subproject commit c7eac74cf1f7e03b06f255cfd01e54162a2b9631
diff --git a/decorators.py b/decorators.py
index b7e8c503d09b3434e7165e2ff94b2ec39b5b5535..760fbe1a19424cfac82598c1b76b6f03222a0534 100644
--- a/decorators.py
+++ b/decorators.py
@@ -1,19 +1,11 @@
-from flask import request, flash, abort
-
 from functools import wraps
-from hmac import compare_digest
+
+from flask import flash
 
 from models.database import ALL_MODELS
 from shared import current_user
-from utils import get_csrf_token
 from common import back
 
-ID_KEY = "id"
-KEY_NOT_PRESENT_MESSAGE = "Missing {}_id."
-OBJECT_DOES_NOT_EXIST_MESSAGE = "There is no {} with id {}."
-
-MISSING_VIEW_RIGHT = "Dir fehlenden die nötigen Zugriffsrechte."
-
 
 def default_redirect():
     return back.redirect()
@@ -23,29 +15,7 @@ def login_redirect():
     return back.redirect("login")
 
 
-def db_lookup(*models, check_exists=True):
-    def _decorator(function):
-        @wraps(function)
-        def _decorated_function(*args, **kwargs):
-            for model in models:
-                key = model.__model_name__
-                id_key = "{}_{}".format(key, ID_KEY)
-                if id_key not in kwargs:
-                    flash(KEY_NOT_PRESENT_MESSAGE.format(key), "alert-error")
-                    return default_redirect()
-                obj_id = kwargs[id_key]
-                obj = model.query.filter_by(id=obj_id).first()
-                if check_exists and obj is None:
-                    model_name = model.__class__.__name__
-                    flash(OBJECT_DOES_NOT_EXIST_MESSAGE.format(
-                        model_name, obj_id),
-                        "alert-error")
-                    return default_redirect()
-                kwargs[key] = obj
-                kwargs.pop(id_key)
-            return function(*args, **kwargs)
-        return _decorated_function
-    return _decorator
+MISSING_VIEW_RIGHT = "Dir fehlenden die nötigen Zugriffsrechte."
 
 
 def require_right(right, require_exist):
@@ -92,14 +62,3 @@ def require_publish_right(require_exist=True):
 
 def require_admin_right(require_exist=True):
     return require_right("admin", require_exist)
-
-
-def protect_csrf(function):
-    @wraps(function)
-    def _decorated_function(*args, **kwargs):
-        token = request.args.get("csrf_token")
-        true_token = get_csrf_token()
-        if token is None or not compare_digest(token, true_token):
-            abort(400)
-        return function(*args, **kwargs)
-    return _decorated_function
diff --git a/server.py b/server.py
index 78d228bd5fdb6e3e778723e0e0646fe16930c71d..10eeacdfc3dcdd1399ac8d90c2a84fcd3281797b 100755
--- a/server.py
+++ b/server.py
@@ -31,9 +31,8 @@ from shared import (
 from utils import (
     get_first_unused_int, get_etherpad_text, split_terms, optional_int_arg,
     fancy_join, footnote_hash, get_git_revision, get_max_page_length_exp,
-    get_internal_filename, get_csrf_token, get_current_ip)
+    get_internal_filename, get_current_ip)
 from decorators import (
-    db_lookup, protect_csrf,
     require_private_view_right, require_modify_right, require_publish_right,
     require_admin_right)
 from models.database import (
@@ -56,6 +55,9 @@ from views.tables import (
     TodoMailsTable, DefaultMetasTable, DecisionCategoriesTable)
 from legacy import import_old_todos, import_old_protocols, import_old_todomails
 from common import back
+from common.csrf import protect_csrf, get_csrf_token
+from common.database import db_lookup
+
 
 app = Flask(__name__)
 app.config.from_object(config)
diff --git a/utils.py b/utils.py
index 116a2f157c623617bc501c5fb089c35bdf54fde2..9c75998abcb1580274fb5401215c41a2ce2e0e59 100644
--- a/utils.py
+++ b/utils.py
@@ -1,4 +1,4 @@
-from flask import request, session
+from flask import request
 
 import random
 import string
@@ -14,8 +14,6 @@ import ipaddress
 from socket import getfqdn
 from uuid import uuid4
 import subprocess
-import os
-import hashlib
 
 import config
 
@@ -265,9 +263,3 @@ def get_max_page_length_exp(objects):
 
 def get_internal_filename(protocol, document, filename):
     return "{}-{}-{}".format(protocol.id, document.id, filename)
-
-
-def get_csrf_token():
-    if "_csrf" not in session:
-        session["_csrf"] = hashlib.sha1(os.urandom(64)).hexdigest()
-    return session["_csrf"]
diff --git a/views/tables.py b/views/tables.py
index 7c75dd158a481b14c39730764b852cbc03494fc6..c00612223f212e02f2093df849cc93e88c802aeb 100644
--- a/views/tables.py
+++ b/views/tables.py
@@ -1,6 +1,6 @@
 from flask import Markup, url_for
 from shared import date_filter, datetime_filter, time_filter, current_user
-from utils import get_csrf_token
+from common.csrf import get_csrf_token
 
 import config