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:
1 parent
d33821dd1b
commit
39eb7431e3
2 files changed
+28
-21
No files matched your search
+9
-6
@@ -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
@@ -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,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
Reference in new issue
Block a user