Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log HTTP referer and origin #1429

Merged
merged 3 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/server/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ def before_request_execute():
real_remote_addr=get_real_ip_addr(request),
user_agent=request.user_agent.string,
api_key=api_key,
user_id=(user and user.id)
user_id=(user and user.id),
req_referrer=request.referrer,
req_origin=request.environ.get('HTTP_ORIGIN', '')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Can you move this to right underneath user_agent=... (since they come from the same place (request headers) and because they both identify client context)?

  • Why not just use request.origin? Presumably so you can default to the empty string, but why prefer that over None?

  • We dont need to keep both values; if both are provided, refer[r]er should be a superstring of origin.

Suggested change
req_referrer=request.referrer,
req_origin=request.environ.get('HTTP_ORIGIN', '')
refer_origin=request.referrer or request.origin,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

)

if not _is_public_route() and api_key and not user:
Expand Down Expand Up @@ -171,6 +173,8 @@ def after_request_execute(response):
response_status=response.status,
content_length=response.calculate_content_length(),
elapsed_time_ms=total_time,
req_referrer=request.referrer,
req_origin=request.environ.get('HTTP_ORIGIN', '')
)
return response

Expand Down
17 changes: 17 additions & 0 deletions tests/server/test_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def setUp(self):
app.config["TESTING"] = True
app.config["WTF_CSRF_ENABLED"] = False
app.config["DEBUG"] = False
self.client = app.test_client()

def test_require_all(self):
with self.subTest("all given"):
Expand Down Expand Up @@ -60,3 +61,19 @@ def test_require_any(self):
with self.subTest("one options given with is empty but ok"):
with app.test_request_context("/?abc="):
self.assertTrue(require_any(request, "abc", empty=True))

def test_origin_headers(self):
with self.subTest("referer and origin"):
melange396 marked this conversation as resolved.
Show resolved Hide resolved
with self.assertLogs("server_api", level='INFO') as logs:
self.client.get("/signal_dashboard_status", headers={
"Referer": "https://test.com/test",
"Origin": "https://test.com"
})
output = logs.output
self.assertEqual(len(output), 2) # [before_request, after_request]
self.assertIn("Received API request", output[0])
self.assertIn("\"req_referrer\": \"https://test.com/test\"", output[0])
self.assertIn("\"req_origin\": \"https://test.com\"", output[0])
self.assertIn("Served API request", output[1])
self.assertIn("\"req_referrer\": \"https://test.com/test\"", output[1])
self.assertIn("\"req_origin\": \"https://test.com\"", output[1])
Loading