Skip to content
Snippets Groups Projects
Commit 1d65c1bc authored by Lukas Braun's avatar Lukas Braun
Browse files

Check Origin header before accept/edit/delete

For some protection against CSRF attacks, check if the Origin header is
the weburl we are listening on before handling POSTs to
moderation/{edit,accept}/<doc>.
If the request does not contain an Origin header (which should never be
the case for POST requests in modern browsers), a warning is printed and
the request handled anyway.

It is probably a good idea to implement some CSRF token mechanism to
authenticate requests as well, I'm not sure how robust this Origin
checking stuff really is.
parent 67510463
Branches master
No related tags found
No related merge requests found
......@@ -6,8 +6,9 @@ from jinja2.exceptions import TemplateNotFound
from werkzeug import Local, LocalManager, Response
from werkzeug.routing import Map, Rule
from werkzeug.exceptions import BadRequest
from werkzeug.exceptions import BadRequest, Forbidden
import sys
import os
import netaddr
......@@ -117,6 +118,14 @@ def remote_is_internal_network(request):
return False
def same_origin_only(request):
try:
if request.headers['Origin'] != config.weburl:
raise Forbidden(description="Same-Origin check failed")
except KeyError:
sys.stderr.write("WARNING: No Origin header in request for protected endpoint!\n");
available_themes = set([it[1] for it in config.themes_by_url])
available_themes.add(config.default_theme)
jinja_env = Environment(loader=ThemeSupportTemplateLoader(available_themes), cache_size=0)
......
......@@ -23,7 +23,7 @@ import datetime
from util.web import expose, render_template, profify, completion_hints, \
update_meta_from_request, theme_for_url, local, \
remote_is_internal_network
remote_is_internal_network, same_origin_only
from util.readMetaData import readMeta
from util.general import canonicalize_title, trim_pdf, empty_metadata
from util.univis import get_univis_metadata
......@@ -243,6 +243,8 @@ def upload(request):
def edit_submit(request, document):
failed = False
if request.method == 'POST':
same_origin_only(request)
if document in public_pdf_db:
entry = public_pdf_db[document]
......@@ -310,6 +312,8 @@ def moderate(request, failed=None):
@expose('/moderation/accept/<document>/')
def edit_article(request, document):
if request.method == 'POST':
same_origin_only(request)
if document in moderation_queue_db:
entry = moderation_queue_db[document]
result = update_meta_from_request(entry, request.form)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment