JSON encode the values in the request and cross-origin log lines

User agent, referrer, URL and Origin could fake additional fields with
quotes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
finnandClaude Opus 5.5 committed 2026-10-23 13:55:49 +00:00
1 parent d33821dd1b
commit 39eb7431e3
2 files changed
+28 -21

No files matched your search

+9 -6
View File
@@ -3,6 +3,7 @@ from functools import wraps
from flask import request, session from flask import request, session
from max.crypto import constant_time_compare, get_random_string from max.crypto import constant_time_compare, get_random_string
from max.log_format import format_log_fields
from max.middlewares import BaseMiddleware, get_real_remote_addr from max.middlewares import BaseMiddleware, get_real_remote_addr
CSRF_TOKEN_KEY = "csrf_token" CSRF_TOKEN_KEY = "csrf_token"
@@ -33,12 +34,14 @@ class CsrfMiddleware(BaseMiddleware):
# Stateless check, so it also protects routes without a session (login) # Stateless check, so it also protects routes without a session (login)
if not self.is_origin_allowed(): if not self.is_origin_allowed():
self.app.logger.debug( self.app.logger.debug(
'Blocked cross-origin request %s %s origin="%s" sec_fetch_site="%s" from %s', "Blocked cross-origin request %s",
request.method, format_log_fields(
request.path, method=request.method,
request.headers.get("Origin"), path=request.path,
request.headers.get("Sec-Fetch-Site"), origin=request.headers.get("Origin"),
get_real_remote_addr(self.app), sec_fetch_site=request.headers.get("Sec-Fetch-Site"),
ip=get_real_remote_addr(self.app),
),
) )
return "Cross-origin request blocked", 403 return "Cross-origin request blocked", 403
+19 -15
View File
@@ -6,6 +6,7 @@ from logging.config import dictConfig
from flask import g, request, session from flask import g, request, session
from max.db import database from max.db import database
from max.log_format import format_log_fields
from max.middlewares import get_real_remote_addr from max.middlewares import get_real_remote_addr
from max.translations import TranslationHandler from max.translations import TranslationHandler
@@ -59,21 +60,24 @@ def init_request_logging(app):
# so the response may be None # so the response may be None
response = g.get("response") response = g.get("response")
start = g.get("request_start") start = g.get("request_start")
time_in_ms = f"{(time.time() - start) * 1000:.2f}" if start else None time_in_ms = round((time.time() - start) * 1000, 2) if start else None
app.logger.info( app.logger.info(
'method=%s url=%s ip=%s user_agent="%s" referrer="%s" db_queries=%s ' "%s",
+ "status=%s content_length=%s user_id=%s session=%s lang=%s time_ms=%s", format_log_fields(
request.method, method=request.method,
request.url, url=request.url,
get_real_remote_addr(app), ip=get_real_remote_addr(app),
request.user_agent, user_agent=request.user_agent.string,
request.referrer, referrer=request.referrer,
database.collect_query_count(), db_queries=database.collect_query_count(),
response.status_code if response is not None else 500, status=response.status_code if response is not None else 500,
response.content_length if response is not None else None, content_length=(
session.get("user_id"), response.content_length if response is not None else None
session.get_log_id(), ),
TranslationHandler.get_language(), user_id=session.get("user_id"),
time_in_ms, session=session.get_log_id(),
lang=TranslationHandler.get_language(),
time_ms=time_in_ms,
),
) )