From 2966c1e32c3dc80fc57880b6204e32fd393061fe Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 28 Oct 2026 21:49:52 +0100 Subject: [PATCH] Runtime state guard: hold a provider reference's node and module to the mesh's name pattern, so no credential rides in one (issue 1126) --- node-tools/internal/bus/state.go | 7 +++++-- node-tools/internal/bus/state_test.go | 5 +++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/node-tools/internal/bus/state.go b/node-tools/internal/bus/state.go index d4dee76..a673168 100644 --- a/node-tools/internal/bus/state.go +++ b/node-tools/internal/bus/state.go @@ -432,7 +432,7 @@ func credentialField(value json.RawMessage) string { return walk(v) } -// providerReference says whether v is exactly {"node": , "module": }. +// providerReference says whether v is exactly {"node": , "module": }, each a name as mesh-sdk names them. func providerReference(v any) bool { m, ok := v.(map[string]any) if !ok || len(m) != 2 { @@ -440,5 +440,8 @@ func providerReference(v any) bool { } node, okN := m["node"].(string) module, okM := m["module"].(string) - return okN && okM && node != "" && module != "" + return okN && okM && referenceName.MatchString(node) && referenceName.MatchString(module) } + +// referenceName is a node's or a module's name as mesh-sdk names them: lower case, digits and dashes. +var referenceName = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`) diff --git a/node-tools/internal/bus/state_test.go b/node-tools/internal/bus/state_test.go index cc85f48..6ce8393 100644 --- a/node-tools/internal/bus/state_test.go +++ b/node-tools/internal/bus/state_test.go @@ -20,8 +20,9 @@ func TestACredentialNamedFieldIsFoundAnywhereInAValue(t *testing.T) { `{"secret":{"value":"s"}}`: "secret", `{"secret":{"node":"anchor","module":"mesh-vault","value":"s"}}`: "secret", `{"secret":{"node":"anchor","module":7}}`: "secret", - `{"secret":["s"]}`: "secret", - `{"bindings":{"secret":{"token":"s"}}}`: "secret", + `{"secret":{"node":"anchor","module":"hunter2 Bearer s3cr3t"}}`: "secret", + `{"secret":["s"]}`: "secret", + `{"bindings":{"secret":{"token":"s"}}}`: "secret", } { if got := credentialField(json.RawMessage(value)); got != want { t.Errorf("%s: found %q, want %q", value, got, want)