From 2e06d383ac3bc503ecd99400bd9b2685739165b2 Mon Sep 17 00:00:00 2001 From: junior Date: Wed, 8 Apr 2026 16:40:53 +0000 Subject: [PATCH] feat(project): increase securityTokenHeader max_length from 20 to 64 The security token header field was capped at 20 characters, which is too restrictive for common header names (e.g. X-Custom-Security-Header). Increase the limit to 64 to accommodate real-world use cases. Add test_security_token_header_max_length to cover boundary acceptance (exactly 64 chars) and rejection (65 chars), matching prior art test patterns for field length validation in this test class. --- src/sentry/core/endpoints/project_details.py | 2 +- .../sentry/core/endpoints/test_project_details.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/sentry/core/endpoints/project_details.py b/src/sentry/core/endpoints/project_details.py index 5b70d26b87dc65..e16c8778e83729 100644 --- a/src/sentry/core/endpoints/project_details.py +++ b/src/sentry/core/endpoints/project_details.py @@ -229,7 +229,7 @@ class ProjectAdminSerializer(ProjectMemberSerializer): r"^[-a-zA-Z0-9+/=\s]+$", max_length=255, allow_blank=True ) securityTokenHeader = serializers.RegexField( - r"^[a-zA-Z0-9_\-]+$", max_length=20, allow_blank=True + r"^[a-zA-Z0-9_\-]+$", max_length=64, allow_blank=True ) verifySSL = serializers.BooleanField(required=False) diff --git a/tests/sentry/core/endpoints/test_project_details.py b/tests/sentry/core/endpoints/test_project_details.py index c38dac58c9f816..ef43d69a979c19 100644 --- a/tests/sentry/core/endpoints/test_project_details.py +++ b/tests/sentry/core/endpoints/test_project_details.py @@ -844,6 +844,20 @@ def test_security_token_header(self) -> None: assert self.project.get_option("sentry:token_header") == "" assert resp.data["securityTokenHeader"] == "" + def test_security_token_header_max_length(self) -> None: + # exactly 64 characters should succeed + value = "X-" + "A" * 62 + assert len(value) == 64 + resp = self.get_success_response(self.org_slug, self.proj_slug, securityTokenHeader=value) + assert self.project.get_option("sentry:token_header") == value + assert resp.data["securityTokenHeader"] == value + + # 65 characters should fail + resp = self.get_error_response( + self.org_slug, self.proj_slug, securityTokenHeader="X-" + "A" * 63, status_code=400 + ) + assert b"securityTokenHeader" in resp.content + def test_verify_ssl(self) -> None: resp = self.get_success_response(self.org_slug, self.proj_slug, verifySSL=False) assert self.project.get_option("sentry:verify_ssl") is False