Merge pull request #248 from copenhagentruckwash/fix-authenticated-ssrf-in-broker-diagnostics

Prevent SSRF in broker diagnostics by ignoring caller URLs and redacting probe output
This commit is contained in:
Jeppe B
2026-06-01 23:49:24 +02:00
committed by GitHub
3 changed files with 37 additions and 21 deletions
@@ -4036,12 +4036,8 @@ BASH;
$target = strtolower(trim((string)($options['target'] ?? 'all')));
$target = in_array($target, ['internal', 'public', 'secret', 'all'], true) ? $target : 'all';
$internalUrl = $this->normalizeBrokerDiagnosticBaseUrl(
array_key_exists('broker_url', $options) ? $options['broker_url'] : $this->configuredBrokerInternalUrl()
);
$publicConfigured = array_key_exists('public_broker_url', $options)
? trim((string)$options['public_broker_url'])
: $this->configuredPublicBrokerUrl();
$internalUrl = $this->normalizeBrokerDiagnosticBaseUrl($this->configuredBrokerInternalUrl());
$publicConfigured = $this->configuredPublicBrokerUrl();
$publicUrl = $this->normalizeBrokerDiagnosticBaseUrl(
$publicConfigured !== '' ? $publicConfigured : $this->deriveBrokerPublicUrl()
);
@@ -4133,7 +4129,7 @@ BASH;
$health = $this->brokerHttpProbe($baseUrl['url'] . '/api/health');
if (($health['status_code'] ?? null) === 200 && !empty($health['json']['ok'])) {
return array_merge($health, [
return array_merge($this->redactBrokerDiagnosticProbe($health), [
'ok' => true,
'status' => 'connected',
'url' => $baseUrl['url'],
@@ -4142,7 +4138,7 @@ BASH;
}
if (($health['status_code'] ?? null) === 404 && $this->isBrokerNotFoundProbe($health)) {
return array_merge($health, [
return array_merge($this->redactBrokerDiagnosticProbe($health), [
'ok' => true,
'status' => 'connected_legacy',
'url' => $baseUrl['url'],
@@ -4151,7 +4147,7 @@ BASH;
}
if (($health['status_code'] ?? null) !== null) {
return array_merge($health, [
return array_merge($this->redactBrokerDiagnosticProbe($health), [
'ok' => false,
'status' => 'unexpected_response',
'url' => $baseUrl['url'],
@@ -4159,7 +4155,7 @@ BASH;
]);
}
return array_merge($health, [
return array_merge($this->redactBrokerDiagnosticProbe($health), [
'ok' => false,
'status' => 'unreachable',
'url' => $baseUrl['url'],
@@ -4187,7 +4183,7 @@ BASH;
if (($diagnostic['status_code'] ?? null) === 200 && !empty($diagnostic['json']['ok'])) {
$required = (bool)($diagnostic['json']['shared_secret_required'] ?? false);
return array_merge($diagnostic, [
return array_merge($this->redactBrokerDiagnosticProbe($diagnostic), [
'ok' => true,
'status' => $required ? 'validated' : 'not_required',
'url' => $baseUrl['url'],
@@ -4198,7 +4194,7 @@ BASH;
}
if (($diagnostic['status_code'] ?? null) === 403) {
return array_merge($diagnostic, [
return array_merge($this->redactBrokerDiagnosticProbe($diagnostic), [
'ok' => false,
'status' => 'secret_rejected',
'url' => $baseUrl['url'],
@@ -4211,7 +4207,7 @@ BASH;
}
if (($diagnostic['status_code'] ?? null) !== null) {
return array_merge($diagnostic, [
return array_merge($this->redactBrokerDiagnosticProbe($diagnostic), [
'ok' => false,
'status' => 'unexpected_response',
'url' => $baseUrl['url'],
@@ -4219,7 +4215,7 @@ BASH;
]);
}
return array_merge($diagnostic, [
return array_merge($this->redactBrokerDiagnosticProbe($diagnostic), [
'ok' => false,
'status' => 'unreachable',
'url' => $baseUrl['url'],
@@ -4242,7 +4238,7 @@ BASH;
);
if (($legacy['status_code'] ?? null) === 200 && !empty($legacy['json']['ok'])) {
return array_merge($legacy, [
return array_merge($this->redactBrokerDiagnosticProbe($legacy), [
'ok' => true,
'status' => 'validated_legacy',
'url' => $baseUrl['url'],
@@ -4251,7 +4247,7 @@ BASH;
}
if (($legacy['status_code'] ?? null) === 403) {
return array_merge($legacy, [
return array_merge($this->redactBrokerDiagnosticProbe($legacy), [
'ok' => false,
'status' => 'secret_rejected',
'url' => $baseUrl['url'],
@@ -4259,7 +4255,7 @@ BASH;
]);
}
return array_merge($legacy, [
return array_merge($this->redactBrokerDiagnosticProbe($legacy), [
'ok' => false,
'status' => ($legacy['status_code'] ?? null) === null ? 'unreachable' : 'unexpected_response',
'url' => $baseUrl['url'],
@@ -4267,6 +4263,17 @@ BASH;
]);
}
/**
* @param array<string,mixed> $probe
* @return array<string,mixed>
*/
private function redactBrokerDiagnosticProbe(array $probe): array
{
unset($probe['json']);
$probe['body_excerpt'] = null;
return $probe;
}
/**
* @param array{url:?string,error:?string} $baseUrl
* @return array<string,mixed>
@@ -4345,7 +4352,7 @@ BASH;
'elapsed_ms' => $elapsedMs,
'error' => null,
'json' => is_array($decoded) ? $decoded : null,
'body_excerpt' => self::trimInstallSessionText($body, 512),
'body_excerpt' => null,
];
}