Moderate severityNVD Advisory· Published Jul 8, 2025· Updated Jul 8, 2025
Sensitive log retrieval in Juju
CVE-2025-53512
Description
The /log endpoint on a Juju controller lacked sufficient authorization checks, allowing unauthorized users to access debug messages that could contain sensitive information.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/juju/jujuGo | < 0.0.0-20250619024904-402ff008dcc2 | 0.0.0-20250619024904-402ff008dcc2 |
Affected products
1- Range: 2.0.0
Patches
2c91a1f404695fix: ensure that users wanting to use debug-log via the /log
3 files changed · +41 −28
apiserver/apiserver.go+11 −6 modified@@ -48,6 +48,7 @@ import ( coredatabase "github.com/juju/juju/core/database" "github.com/juju/juju/core/lease" "github.com/juju/juju/core/multiwatcher" + "github.com/juju/juju/core/permission" "github.com/juju/juju/core/presence" "github.com/juju/juju/core/resources" "github.com/juju/juju/internal/worker/syslogger" @@ -707,15 +708,19 @@ func (srv *Server) endpoints() ([]apihttp.Endpoint, error) { healthHandler := srv.monitoredHandler(http.HandlerFunc(srv.healthHandler), "health") logStreamHandler := srv.monitoredHandler(newLogStreamEndpointHandler(httpCtxt), "logstream") embeddedCLIHandler := srv.monitoredHandler(newEmbeddedCLIHandler(httpCtxt), "commands") + var debuglogAuth httpcontext.CompositeAuthorizer = []authentication.Authorizer{ + tagKindAuthorizer{names.MachineTagKind, names.ControllerAgentTagKind}, + controllerAdminAuthorizer{ + controllerTag: systemState.ControllerTag(), + }, + modelPermissionAuthorizer{ + perm: permission.ReadAccess, + }, + } debugLogHandler := srv.monitoredHandler(newDebugLogDBHandler( httpCtxt, httpAuthenticator, - tagKindAuthorizer{ - names.MachineTagKind, - names.ControllerAgentTagKind, - names.UserTagKind, - names.ApplicationTagKind, - }, + debuglogAuth, ), "log") pubsubHandler := srv.monitoredHandler(newPubSubHandler(httpCtxt, srv.shared.centralHub), "pubsub") logSinkHandler := logsink.NewHTTPHandler(
apiserver/debuglog_db_test.go+18 −2 modified@@ -14,6 +14,7 @@ import ( apitesting "github.com/juju/juju/apiserver/testing" "github.com/juju/juju/apiserver/websocket/websockettest" + "github.com/juju/juju/core/permission" "github.com/juju/juju/rpc/params" "github.com/juju/juju/testing/factory" ) @@ -59,16 +60,17 @@ func (s *debugLogDBSuite) TestUnitLoginsRejected(c *gc.C) { conn, _, err := s.dialWebsocketInternal(c, nil, header) c.Assert(err, jc.ErrorIsNil) - websockettest.AssertJSONError(c, conn, "authorization failed: tag kind unit not valid") + websockettest.AssertJSONError(c, conn, "authorization failed: permission denied") websockettest.AssertWebsocketClosed(c, conn) } var noResultsPlease = url.Values{"maxLines": {"0"}, "noTail": {"true"}} -func (s *debugLogDBSuite) TestUserLoginsAccepted(c *gc.C) { +func (s *debugLogDBSuite) TestUserLoginAccepted(c *gc.C) { u := s.Factory.MakeUser(c, &factory.UserParams{ Name: "oryx", Password: "gardener", + Access: permission.ReadAccess, }) header := jujuhttp.BasicAuthHeader(u.Tag().String(), "gardener") conn, _, err := s.dialWebsocketInternal(c, noResultsPlease, header) @@ -80,6 +82,20 @@ func (s *debugLogDBSuite) TestUserLoginsAccepted(c *gc.C) { c.Assert(result.Error, gc.IsNil) } +func (s *debugLogDBSuite) TestUserLoginRejected(c *gc.C) { + u := s.Factory.MakeUser(c, &factory.UserParams{ + Name: "oryx", + Password: "gardener", + NoModelUser: true, + }) + header := jujuhttp.BasicAuthHeader(u.Tag().String(), "gardener") + conn, _, err := s.dialWebsocketInternal(c, noResultsPlease, header) + c.Assert(err, jc.ErrorIsNil) + + websockettest.AssertJSONError(c, conn, "authorization failed: permission denied") + websockettest.AssertWebsocketClosed(c, conn) +} + func (s *debugLogDBSuite) TestMachineLoginsAccepted(c *gc.C) { m, password := s.Factory.MakeMachineReturningPassword(c, &factory.MachineParams{ Nonce: "foo-nonce",
go.sum+12 −20 modified@@ -18,8 +18,7 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go/auth v0.16.1 h1:XrXauHMd30LhQYVRHLGvJiYeczweKQXZxsTbV9TiguU= -cloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI= +cloud.google.com/go/auth v0.16.2 h1:QvBAGFPLrDeoiNjyfVunhQ10HKNYuOwZ5noee0M5df4= cloud.google.com/go/auth v0.16.2/go.mod h1:sRBas2Y1fB1vZTdurouM0AzuYQBMZinrUYL8EufhtEA= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= @@ -952,21 +951,17 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= -go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= -go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= -go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= -go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= -go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= -go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= -go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= -go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= -go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= +go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= +go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= +go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= @@ -1294,8 +1289,7 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= -google.golang.org/api v0.236.0 h1:CAiEiDVtO4D/Qja2IA9VzlFrgPnK3XVMmRoJZlSWbc0= -google.golang.org/api v0.236.0/go.mod h1:X1WF9CU2oTc+Jml1tiIxGmWFK/UZezdqEu09gcxZAj4= +google.golang.org/api v0.238.0 h1:+EldkglWIg/pWjkq97sd+XxH7PxakNYoe/rkSTbnvOs= google.golang.org/api v0.238.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1349,8 +1343,7 @@ google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRx google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk= google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0= google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1372,8 +1365,7 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8= -google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
402ff008dcc2fix: ensure that users wanting to use debug-log via the /log
2 files changed · +31 −3
apiserver/apiserver.go+13 −1 modified@@ -44,6 +44,7 @@ import ( "github.com/juju/juju/core/cache" "github.com/juju/juju/core/lease" "github.com/juju/juju/core/multiwatcher" + "github.com/juju/juju/core/permission" "github.com/juju/juju/core/presence" "github.com/juju/juju/core/resources" "github.com/juju/juju/feature" @@ -689,9 +690,20 @@ func (srv *Server) endpoints() ([]apihttp.Endpoint, error) { healthHandler := http.HandlerFunc(srv.healthHandler) logStreamHandler := newLogStreamEndpointHandler(httpCtxt) embeddedCLIHandler := newEmbeddedCLIHandler(httpCtxt) + var debuglogAuth httpcontext.CompositeAuthorizer = []httpcontext.Authorizer{ + tagKindAuthorizer{names.MachineTagKind, names.ControllerAgentTagKind}, + controllerAdminAuthorizer{ + st: systemState, + }, + modelPermissionAuthorizer{ + userAccess: systemState.UserPermission, + perm: permission.ReadAccess, + }, + } debugLogHandler := newDebugLogDBHandler( httpCtxt, srv.authenticator, - tagKindAuthorizer{names.MachineTagKind, names.ControllerAgentTagKind, names.UserTagKind, names.ApplicationTagKind}) + debuglogAuth, + ) pubsubHandler := newPubSubHandler(httpCtxt, srv.shared.centralHub) logSinkHandler := logsink.NewHTTPHandler( newAgentLogWriteCloserFunc(httpCtxt, srv.logSinkWriter, &srv.apiServerLoggers),
apiserver/debuglog_db_test.go+18 −2 modified@@ -14,6 +14,7 @@ import ( apitesting "github.com/juju/juju/apiserver/testing" "github.com/juju/juju/apiserver/websocket/websockettest" + "github.com/juju/juju/core/permission" "github.com/juju/juju/rpc/params" "github.com/juju/juju/testing/factory" ) @@ -59,16 +60,17 @@ func (s *debugLogDBSuite) TestUnitLoginsRejected(c *gc.C) { conn, _, err := s.dialWebsocketInternal(c, nil, header) c.Assert(err, jc.ErrorIsNil) - websockettest.AssertJSONError(c, conn, "authorization failed: tag kind unit not valid") + websockettest.AssertJSONError(c, conn, "authorization failed: permission denied") websockettest.AssertWebsocketClosed(c, conn) } var noResultsPlease = url.Values{"maxLines": {"0"}, "noTail": {"true"}} -func (s *debugLogDBSuite) TestUserLoginsAccepted(c *gc.C) { +func (s *debugLogDBSuite) TestUserLoginAccepted(c *gc.C) { u := s.Factory.MakeUser(c, &factory.UserParams{ Name: "oryx", Password: "gardener", + Access: permission.ReadAccess, }) header := jujuhttp.BasicAuthHeader(u.Tag().String(), "gardener") conn, _, err := s.dialWebsocketInternal(c, noResultsPlease, header) @@ -80,6 +82,20 @@ func (s *debugLogDBSuite) TestUserLoginsAccepted(c *gc.C) { c.Assert(result.Error, gc.IsNil) } +func (s *debugLogDBSuite) TestUserLoginRejected(c *gc.C) { + u := s.Factory.MakeUser(c, &factory.UserParams{ + Name: "oryx", + Password: "gardener", + NoModelUser: true, + }) + header := jujuhttp.BasicAuthHeader(u.Tag().String(), "gardener") + conn, _, err := s.dialWebsocketInternal(c, noResultsPlease, header) + c.Assert(err, jc.ErrorIsNil) + + websockettest.AssertJSONError(c, conn, "authorization failed: permission denied") + websockettest.AssertWebsocketClosed(c, conn) +} + func (s *debugLogDBSuite) TestMachineLoginsAccepted(c *gc.C) { m, password := s.Factory.MakeMachineReturningPassword(c, &factory.MachineParams{ Nonce: "foo-nonce",
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-r64v-82fh-xc63ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-53512ghsaADVISORY
- github.com/juju/juju/commit/402ff008dcc2cb57f4441968628637efb5c2a662ghsaWEB
- github.com/juju/juju/commit/c91a1f4046956874ba77c8b398aecee3d61a2dc3ghsaWEB
- github.com/juju/juju/security/advisories/GHSA-r64v-82fh-xc63ghsaWEB
News mentions
0No linked articles in our index yet.