fix: code review — security fixes, dedup, cleanup

- setup: validate roles against users.VALID_ROLES (Supervisor was missing)
- files: fix path traversal prefix-match edge case (is_relative_to),
  dedupe path validation into resolve_upload_path(), use logging not print
- measurements: extract shared _build_measurement_filters() helper
- client app: prevent open redirect via Referer on /set-language
- maker: guard resp.json() in parse-technical-sheet proxy
- measure/maker: extract shared file proxy into services/file_proxy.py
- measure: localize supervisor validation error messages
- annotation-editor: remove global keydown listener in destroy()

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-06-11 12:16:29 +00:00
parent 25a788f430
commit fd571c479e
8 changed files with 141 additions and 134 deletions
+9 -1
View File
@@ -1,6 +1,7 @@
"""TieMeasureFlow Client - Flask Entry Point."""
import json
import os
from urllib.parse import urlparse
from flask import Flask, redirect, url_for, session, request
from flask_babel import Babel
@@ -63,7 +64,14 @@ def create_app() -> Flask:
"""Set user's preferred language and store in session."""
if lang in Config.LANGUAGES:
session["language"] = lang
return redirect(request.referrer or url_for("auth.login"))
# Only follow the referrer if it points back to this host
# (prevents open redirect via a forged Referer header).
referrer = request.referrer
if referrer:
parsed = urlparse(referrer)
if parsed.netloc and parsed.netloc != request.host:
referrer = None
return redirect(referrer or url_for("auth.login"))
@app.template_filter("tojson_attr")
def tojson_attr_filter(value):