Masking secrets after templating creds in HttpRequest Block (#4248)
This commit is contained in:
@@ -235,6 +235,33 @@ class WorkflowRunContext:
|
||||
return self.secrets.get(secret_id_or_value)
|
||||
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]:
|
||||
"""
|
||||
Get the secrets from the password manager. The secrets dict will contain the actual secret values.
|
||||
|
||||
@@ -3913,6 +3913,9 @@ class HttpRequestBlock(Block):
|
||||
"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(
|
||||
"HTTP request completed",
|
||||
status_code=status_code,
|
||||
|
||||
Reference in New Issue
Block a user