Masking secrets after templating creds in HttpRequest Block (#4248)

This commit is contained in:
Marc Kelechava
2025-12-09 11:38:09 -08:00
committed by GitHub
parent eb50fdef83
commit e2c2ec1892
2 changed files with 30 additions and 0 deletions

View File

@@ -235,6 +235,33 @@ class WorkflowRunContext:
return self.secrets.get(secret_id_or_value) return self.secrets.get(secret_id_or_value)
return None return None
def mask_secrets_in_data(self, data: Any, mask: str = "*****") -> Any:
"""
Recursively replace any real secret values in data with a mask.
Used to sanitize HttpRequestBlock output before storing.
Only masks values that exist in self.secrets (registered credentials).
"""
if not self.secrets:
return data
# Collect all non-empty string secret values
secret_values = {v for v in self.secrets.values() if isinstance(v, str) and v}
if not secret_values:
return data
if isinstance(data, str):
result = data
for secret in secret_values:
result = result.replace(secret, mask)
return result
elif isinstance(data, dict):
return {k: self.mask_secrets_in_data(v, mask) for k, v in data.items()}
elif isinstance(data, list):
return [self.mask_secrets_in_data(item, mask) for item in data]
return data
async def get_secrets_from_password_manager(self) -> dict[str, Any]: async def get_secrets_from_password_manager(self) -> dict[str, Any]:
""" """
Get the secrets from the password manager. The secrets dict will contain the actual secret values. Get the secrets from the password manager. The secrets dict will contain the actual secret values.

View File

@@ -3913,6 +3913,9 @@ class HttpRequestBlock(Block):
"url": self.url, "url": self.url,
} }
# Mask secrets in output to prevent credential exposure in DB/UI
response_data = workflow_run_context.mask_secrets_in_data(response_data)
LOG.info( LOG.info(
"HTTP request completed", "HTTP request completed",
status_code=status_code, status_code=status_code,