From 0593b8b0e4279cf015140229795a09df6e3ca8f1 Mon Sep 17 00:00:00 2001 From: jingrui Date: Mon, 12 Aug 2019 19:13:00 +0800 Subject: [PATCH] docker: [backport] fix CVE-2019-13509 ref: https://github.com/moby/moby/commit/e4b9edd31fdba3adf1e39fb9874f73d391f0ff34 Commit 77b8465d7e68ca102d7aae839c7b3fe0ecd28398 added a secret update endpoint to allow updating labels on existing secrets. However, when implementing the endpoint, the DebugRequestMiddleware was not updated to scrub the Data field (as is being done when creating a secret). When updating a secret (to set labels), the Data field should be either `nil` (not set), or contain the same value as the existing secret. In situations where the Data field is set, and the `dockerd` daemon is running with debugging enabled / log-level debug, the base64-encoded value of the secret is printed to the daemon logs. The docker cli does not have a `docker secret update` command, but when using `docker stack deploy`, the docker cli sends the secret data both when _creating_ a stack, and when _updating_ a stack, thus leaking the secret data if the daemon runs with debug enabled: ... Signed-off-by: Sebastiaan van Stijn (cherry picked from commit c7ce4be93ae8edd2da62a588e01c67313a4aba0c) Signed-off-by: Tibor Vass (cherry picked from commit 73db8c77bfb2d0cbdf71ce491f3d3e66c9dd5be6) Signed-off-by: Sebastiaan van Stijn Upstream-commit: 32b40c53662e733b4627b0b303c71b52484a31f4 Change-Id: If571264d227f41cbdcf7dceaa56d7b10ec2a3ee7 Signed-off-by: jingrui --- .../engine/api/server/middleware/debug.go | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/components/engine/api/server/middleware/debug.go b/components/engine/api/server/middleware/debug.go index 2cef1d46c3..31165bf918 100644 --- a/components/engine/api/server/middleware/debug.go +++ b/components/engine/api/server/middleware/debug.go @@ -71,9 +71,22 @@ func maskSecretKeys(inp interface{}, path string) { } if form, ok := inp.(map[string]interface{}); ok { + scrub := []string{ + // Note: The Data field contains the base64-encoded secret in 'secret' + // and 'config' create and update requests. Currently, no other POST + // API endpoints use a data field, so we scrub this field unconditionally. + // Change this handling to be conditional if a new endpoint is added + // in future where this field should not be scrubbed. + "data", + "jointoken", + "password", + "secret", + "signingcakey", + "unlockkey", + } loop0: for k, v := range form { - for _, m := range []string{"password", "secret", "jointoken", "unlockkey", "signingcakey"} { + for _, m := range scrub { if strings.EqualFold(m, k) { form[k] = "*****" continue loop0 @@ -81,14 +94,5 @@ func maskSecretKeys(inp interface{}, path string) { } maskSecretKeys(v, path) } - - // Route-specific redactions - if strings.HasSuffix(path, "/secrets/create") { - for k := range form { - if k == "Data" { - form[k] = "*****" - } - } - } } } -- 2.17.1