diff --git a/util/web.py b/util/web.py index db5fbacb4269aee674932365e93496ea6d7ee193..b051c9a7443c9607230969ff262b7eceb3b1021b 100644 --- a/util/web.py +++ b/util/web.py @@ -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) diff --git a/web/views.py b/web/views.py index 37432839c46b8108acc1a2aeb6caac832983ee07..35c2b056e005ddd9e0ca59da6b6d8fac30096a90 100644 --- a/web/views.py +++ b/web/views.py @@ -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)