fix(vercel): exclude API token from serialization and repr (#11198)

This commit is contained in:
Pedro Martín
2026-05-18 14:30:44 +02:00
committed by GitHub
parent 21df5c58b1
commit 5ca6e31f45
3 changed files with 51 additions and 1 deletions
+1
View File
@@ -25,6 +25,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
- `zone_waf_enabled` check for Cloudflare provider now appends a plan-aware hint to the FAIL `status_extended`: a possible-false-positive note on paid plans (Pro, Business, Enterprise) where the legacy `waf` zone setting can read `off` even though WAF managed rulesets are deployed via the dashboard, and a "not available on the Cloudflare Free plan" note on Free zones [(#9896)](https://github.com/prowler-cloud/prowler/pull/9896)
- Google Workspace Gmail checks sharing a single resource row, causing the service field to be overwritten by the last check executed [(#11169)](https://github.com/prowler-cloud/prowler/pull/11169)
- Google Workspace Drive and Calendar services missing server-side policy filters [(#11195)](https://github.com/prowler-cloud/prowler/pull/11195)
- `VercelSession.token` is now excluded from serialization and representation to prevent the Vercel API token from leaking through `.dict()`, `.json()` or logs [(#11198)](https://github.com/prowler-cloud/prowler/pull/11198)
---
+1 -1
View File
@@ -9,7 +9,7 @@ from prowler.providers.common.models import ProviderOutputOptions
class VercelSession(BaseModel):
"""Vercel API session information."""
token: str
token: str = Field(exclude=True, repr=False)
team_id: Optional[str] = None
base_url: str = "https://api.vercel.com"
http_session: Any = Field(default=None, exclude=True)
@@ -222,3 +222,52 @@ class TestVercelProviderTestConnection:
with pytest.raises(VercelCredentialsError):
VercelProvider.test_connection(raise_on_exception=True)
class TestVercelSessionTokenSecurity:
"""The Vercel API token must never leak through serialization or repr."""
def test_token_is_still_accessible_as_attribute(self):
session = VercelSession(token=API_TOKEN, team_id=TEAM_ID)
assert session.token == API_TOKEN
def test_token_excluded_from_dict(self):
session = VercelSession(token=API_TOKEN, team_id=TEAM_ID)
serialized = session.dict()
assert "token" not in serialized
assert API_TOKEN not in str(serialized)
assert serialized["team_id"] == TEAM_ID
def test_token_excluded_from_model_dump(self):
session = VercelSession(token=API_TOKEN, team_id=TEAM_ID)
serialized = session.model_dump()
assert "token" not in serialized
assert API_TOKEN not in str(serialized)
def test_token_excluded_from_json(self):
session = VercelSession(token=API_TOKEN, team_id=TEAM_ID)
serialized = session.json()
assert "token" not in serialized
assert API_TOKEN not in serialized
def test_token_excluded_from_model_dump_json(self):
session = VercelSession(token=API_TOKEN, team_id=TEAM_ID)
serialized = session.model_dump_json()
assert "token" not in serialized
assert API_TOKEN not in serialized
def test_token_excluded_from_repr_and_str(self):
session = VercelSession(token=API_TOKEN, team_id=TEAM_ID)
assert API_TOKEN not in repr(session)
assert API_TOKEN not in str(session)
assert "token" not in repr(session)