Token in custom credentials object can leak through logs in ydb-go-sdk
Description
ydb-go-sdk v3.48.6 to v3.53.2 leaks custom credentials into logs via error messages; upgrade to v3.53.3 or implement fmt.Stringer.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
ydb-go-sdk v3.48.6 to v3.53.2 leaks custom credentials into logs via error messages; upgrade to v3.53.3 or implement fmt.Stringer.
Vulnerability
Description In versions v3.48.6 through v3.53.2 of ydb-go-sdk, custom credentials objects implementing the Credentials interface are inadvertently serialized into error messages. The root cause is the use of fmt.Errorf("something went wrong (credentials: %q)", credentials) during connection attempts, which triggers the default Go formatting of the credentials object. This behavior can expose sensitive authentication data in log files [1].
Exploitation
Conditions An attacker must have access to application logs where such connection errors are recorded. No authentication or network position is required beyond log access. The vulnerability is passive: the credentials are only leaked if an error occurs during connection setup, but any such event will embed the full credentials object into the log entry [1].
Impact
If an attacker obtains the leaked credentials, they can authenticate to the YDB database with the same privileges as the legitimate application. This could lead to unauthorized data access, modification, or deletion, depending on the database permissions [1].
Mitigation
The fix was released in version v3.53.3, which removes the problematic formatting. Users unable to upgrade should implement the fmt.Stringer interface on their custom credentials types to explicitly control what is logged. The relevant commit (a0d9205) shows the removal of %q formatting and related changes [3].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/ydb-platform/ydb-go-sdk/v3Go | >= 3.48.6, < 3.53.3 | 3.53.3 |
Affected products
2- Range: >= 3.48.6, < 3.53.3
Patches
1a0d92057c4e1Merge pull request #859 from ydb-platform/obfuscate-access-token
15 files changed · +412 −140
CHANGELOG.md+3 −0 modified@@ -1,3 +1,6 @@ +* Refactored credentials options (from funcs to interfaces and types) +* Fixed stringification of credentials object + ## v3.53.2 * Fixed panic when try to unwrap values with more than 127 columns with custom ydb unmarshaler
connection.go+2 −1 modified@@ -465,7 +465,8 @@ func connect(ctx context.Context, c *Driver) error { c.config = c.config.With(config.WithCredentials( credentials.NewStaticCredentials( c.userInfo.User, c.userInfo.Password, - c.config, + c.config.Endpoint(), + credentials.WithGrpcDialOptions(c.config.GrpcDialOptions()...), ), )) }
credentials/credentials.go+12 −57 modified@@ -3,10 +3,7 @@ package credentials import ( "context" - "google.golang.org/grpc" - "github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials" - "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack" ) // Credentials is an interface of YDB credentials required for connect with YDB @@ -15,67 +12,25 @@ type Credentials interface { Token(context.Context) (string, error) } -type optionsHolder struct { - sourceInfo string -} - -type option func(h *optionsHolder) - -// WithSourceInfo option append to credentials object the source info for reporting source info details on error case -func WithSourceInfo(sourceInfo string) option { - return func(h *optionsHolder) { - h.sourceInfo = sourceInfo - } -} - // NewAccessTokenCredentials makes access token credentials object // Passed options redefines default values of credentials object internal fields -func NewAccessTokenCredentials(accessToken string, opts ...option) *credentials.AccessToken { - h := &optionsHolder{ - sourceInfo: stack.Record(1), - } - for _, o := range opts { - if o != nil { - o(h) - } - } - return credentials.NewAccessTokenCredentials(accessToken, credentials.WithSourceInfo(h.sourceInfo)) +func NewAccessTokenCredentials( + accessToken string, opts ...credentials.AccessTokenCredentialsOption, +) *credentials.AccessToken { + return credentials.NewAccessTokenCredentials(accessToken, opts...) } // NewAnonymousCredentials makes anonymous credentials object // Passed options redefines default values of credentials object internal fields -func NewAnonymousCredentials(opts ...option) *credentials.Anonymous { - h := &optionsHolder{ - sourceInfo: stack.Record(1), - } - for _, o := range opts { - if o != nil { - o(h) - } - } - return credentials.NewAnonymousCredentials(credentials.WithSourceInfo(h.sourceInfo)) -} - -type staticCredentialsConfig struct { - authEndpoint string - opts []grpc.DialOption -} - -func (s staticCredentialsConfig) Endpoint() string { - return s.authEndpoint -} - -func (s staticCredentialsConfig) GrpcDialOptions() []grpc.DialOption { - return s.opts +func NewAnonymousCredentials( + opts ...credentials.AnonymousCredentialsOption, +) *credentials.Anonymous { + return credentials.NewAnonymousCredentials(opts...) } // NewStaticCredentials makes static credentials object -func NewStaticCredentials(user, password, authEndpoint string, opts ...grpc.DialOption) *credentials.Static { - return credentials.NewStaticCredentials(user, password, - staticCredentialsConfig{ - authEndpoint: authEndpoint, - opts: opts, - }, - credentials.WithSourceInfo(stack.Record(1)), - ) +func NewStaticCredentials( + user, password, authEndpoint string, opts ...credentials.StaticCredentialsOption, +) *credentials.Static { + return credentials.NewStaticCredentials(user, password, authEndpoint, opts...) }
credentials/options.go+17 −0 added@@ -0,0 +1,17 @@ +package credentials + +import ( + "google.golang.org/grpc" + + "github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials" +) + +// WithSourceInfo option append to credentials object the source info for reporting source info details on error case +func WithSourceInfo(sourceInfo string) credentials.SourceInfoOption { + return credentials.WithSourceInfo(sourceInfo) +} + +// WithGrpcDialOptions option append to static credentials object GRPC dial options +func WithGrpcDialOptions(opts ...grpc.DialOption) credentials.StaticCredentialsOption { + return credentials.WithGrpcDialOptions(opts...) +}
internal/balancer/balancer.go+12 −8 modified@@ -11,6 +11,7 @@ import ( balancerConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/balancer/config" "github.com/ydb-platform/ydb-go-sdk/v3/internal/closer" "github.com/ydb-platform/ydb-go-sdk/v3/internal/conn" + "github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials" internalDiscovery "github.com/ydb-platform/ydb-go-sdk/v3/internal/discovery" discoveryConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/discovery/config" "github.com/ydb-platform/ydb-go-sdk/v3/internal/endpoint" @@ -66,14 +67,10 @@ func (b *Balancer) clusterDiscovery(ctx context.Context) (err error) { if err = retry.Retry(ctx, func(childCtx context.Context) (err error) { if err = b.clusterDiscoveryAttempt(childCtx); err != nil { if xerrors.IsTransportError(err, grpcCodes.Unauthenticated) { - return xerrors.WithStackTrace( - fmt.Errorf( - "cluster discovery failed: %w (endpoint: %q, database: %q, credentials: %q)", - err, - b.driverConfig.Endpoint(), - b.driverConfig.Database(), - b.driverConfig.Credentials(), - ), + return credentials.UnauthenticatedError("cluster discovery failed", err, + credentials.WithEndpoint(b.driverConfig.Endpoint()), + credentials.WithDatabase(b.driverConfig.Database()), + credentials.WithCredentials(b.driverConfig.Credentials()), ) } // if got err but parent context is not done - mark error as retryable @@ -298,6 +295,13 @@ func (b *Balancer) wrapCall(ctx context.Context, f func(ctx context.Context, cc if err = f(ctx, cc); err != nil { if conn.UseWrapping(ctx) { + if xerrors.IsTransportError(err, grpcCodes.Unauthenticated) { + err = credentials.UnauthenticatedError("unauthenticated", err, + credentials.WithAddress(cc.Endpoint().String()), + credentials.WithNodeID(cc.Endpoint().NodeID()), + credentials.WithCredentials(b.driverConfig.Credentials()), + ) + } return xerrors.WithStackTrace(err) } return err
internal/conn/middleware.go+0 −18 modified@@ -80,21 +80,3 @@ func WithBeforeFunc( }, } } - -func WithAfterFunc( - cc grpc.ClientConnInterface, - after func(), -) grpc.ClientConnInterface { - return &middleware{ - invoke: func(ctx context.Context, method string, args interface{}, reply interface{}, opts ...grpc.CallOption) error { - defer after() - return cc.Invoke(ctx, method, args, reply, opts...) - }, - newStream: func(ctx context.Context, desc *grpc.StreamDesc, method string, opts ...grpc.CallOption) ( - grpc.ClientStream, error, - ) { - defer after() - return cc.NewStream(ctx, desc, method, opts...) - }, - } -}
internal/credentials/access_token.go+23 −10 modified@@ -4,33 +4,37 @@ import ( "context" "fmt" + "github.com/ydb-platform/ydb-go-sdk/v3/internal/allocator" "github.com/ydb-platform/ydb-go-sdk/v3/internal/secret" "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack" ) var ( - _ Credentials = (*AccessToken)(nil) - _ fmt.Stringer = (*AccessToken)(nil) + _ Credentials = (*AccessToken)(nil) + _ fmt.Stringer = (*AccessToken)(nil) + _ AccessTokenCredentialsOption = SourceInfoOption("") ) +type AccessTokenCredentialsOption interface { + ApplyAccessTokenCredentialsOption(c *AccessToken) +} + // AccessToken implements Credentials interface with static // authorization parameters. type AccessToken struct { token string sourceInfo string } -func NewAccessTokenCredentials(token string, opts ...Option) *AccessToken { - options := optionsHolder{ +func NewAccessTokenCredentials(token string, opts ...AccessTokenCredentialsOption) *AccessToken { + c := &AccessToken{ + token: token, sourceInfo: stack.Record(1), } for _, opt := range opts { - opt(&options) - } - return &AccessToken{ - token: token, - sourceInfo: options.sourceInfo, + opt.ApplyAccessTokenCredentialsOption(c) } + return c } // Token implements Credentials. @@ -40,5 +44,14 @@ func (c AccessToken) Token(_ context.Context) (string, error) { // Token implements Credentials. func (c AccessToken) String() string { - return fmt.Sprintf("AccessToken(token:%q,from:%q)", secret.Token(c.token), c.sourceInfo) + buffer := allocator.Buffers.Get() + defer allocator.Buffers.Put(buffer) + buffer.WriteString("AccessToken(token:") + fmt.Fprintf(buffer, "%q", secret.Token(c.token)) + if c.sourceInfo != "" { + buffer.WriteString(",from:") + fmt.Fprintf(buffer, "%q", c.sourceInfo) + } + buffer.WriteByte(')') + return buffer.String() }
internal/credentials/anonymous.go+21 −9 modified@@ -4,29 +4,33 @@ import ( "context" "fmt" + "github.com/ydb-platform/ydb-go-sdk/v3/internal/allocator" "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack" ) var ( - _ Credentials = (*Anonymous)(nil) - _ fmt.Stringer = (*Anonymous)(nil) + _ Credentials = (*Anonymous)(nil) + _ fmt.Stringer = (*Anonymous)(nil) + _ AnonymousCredentialsOption = SourceInfoOption("") ) +type AnonymousCredentialsOption interface { + ApplyAnonymousCredentialsOption(c *Anonymous) +} + // Anonymous implements Credentials interface with Anonymous access type Anonymous struct { sourceInfo string } -func NewAnonymousCredentials(opts ...Option) *Anonymous { - options := optionsHolder{ +func NewAnonymousCredentials(opts ...AnonymousCredentialsOption) *Anonymous { + c := &Anonymous{ sourceInfo: stack.Record(1), } for _, opt := range opts { - opt(&options) - } - return &Anonymous{ - sourceInfo: options.sourceInfo, + opt.ApplyAnonymousCredentialsOption(c) } + return c } // Token implements Credentials. @@ -36,5 +40,13 @@ func (c Anonymous) Token(_ context.Context) (string, error) { // Token implements Credentials. func (c Anonymous) String() string { - return fmt.Sprintf("Anonymous(from:%q)", c.sourceInfo) + buffer := allocator.Buffers.Get() + defer allocator.Buffers.Put(buffer) + buffer.WriteString("Anonymous(") + if c.sourceInfo != "" { + buffer.WriteString("from:") + fmt.Fprintf(buffer, "%q", c.sourceInfo) + } + buffer.WriteByte(')') + return buffer.String() }
internal/credentials/options.go+0 −13 removed@@ -1,13 +0,0 @@ -package credentials - -type optionsHolder struct { - sourceInfo string -} - -type Option func(opts *optionsHolder) - -func WithSourceInfo(sourceInfo string) Option { - return func(opts *optionsHolder) { - opts.sourceInfo = sourceInfo - } -}
internal/credentials/source_info.go+20 −0 added@@ -0,0 +1,20 @@ +package credentials + +type SourceInfoOption string + +func (sourceInfo SourceInfoOption) ApplyStaticCredentialsOption(h *Static) { + h.sourceInfo = string(sourceInfo) +} + +func (sourceInfo SourceInfoOption) ApplyAnonymousCredentialsOption(h *Anonymous) { + h.sourceInfo = string(sourceInfo) +} + +func (sourceInfo SourceInfoOption) ApplyAccessTokenCredentialsOption(h *AccessToken) { + h.sourceInfo = string(sourceInfo) +} + +// WithSourceInfo option append to credentials object the source info for reporting source info details on error case +func WithSourceInfo(sourceInfo string) SourceInfoOption { + return SourceInfoOption(sourceInfo) +}
internal/credentials/static.go+40 −20 modified@@ -13,30 +13,43 @@ import ( "github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Operations" "google.golang.org/grpc" + "github.com/ydb-platform/ydb-go-sdk/v3/internal/allocator" "github.com/ydb-platform/ydb-go-sdk/v3/internal/secret" "github.com/ydb-platform/ydb-go-sdk/v3/internal/stack" "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors" ) -type staticCredentialsConfig interface { - Endpoint() string - GrpcDialOptions() []grpc.DialOption +var ( + _ Credentials = (*Static)(nil) + _ fmt.Stringer = (*Static)(nil) + _ StaticCredentialsOption = grpcDialOptionsOption(nil) +) + +type grpcDialOptionsOption []grpc.DialOption + +func (opts grpcDialOptionsOption) ApplyStaticCredentialsOption(c *Static) { + c.opts = opts +} + +type StaticCredentialsOption interface { + ApplyStaticCredentialsOption(c *Static) +} + +func WithGrpcDialOptions(opts ...grpc.DialOption) grpcDialOptionsOption { + return opts } -func NewStaticCredentials(user, password string, config staticCredentialsConfig, opts ...Option) *Static { - options := optionsHolder{ +func NewStaticCredentials(user, password, endpoint string, opts ...StaticCredentialsOption) *Static { + c := &Static{ + user: user, + password: password, + endpoint: endpoint, sourceInfo: stack.Record(1), } for _, opt := range opts { - opt(&options) - } - return &Static{ - user: user, - password: password, - endpoint: config.Endpoint(), - sourceInfo: options.sourceInfo, - opts: config.GrpcDialOptions(), + opt.ApplyStaticCredentialsOption(c) } + return c } var ( @@ -132,11 +145,18 @@ func parseExpiresAt(raw string) (expiresAt time.Time, err error) { } func (c *Static) String() string { - return fmt.Sprintf( - "Static(user:%q,password:%q,token:%q,from:%q)", - c.user, - secret.Password(c.password), - secret.Token(c.token), - c.sourceInfo, - ) + buffer := allocator.Buffers.Get() + defer allocator.Buffers.Put(buffer) + buffer.WriteString("Static(user:") + fmt.Fprintf(buffer, "%q", c.user) + buffer.WriteString(",password:") + fmt.Fprintf(buffer, "%q", secret.Password(c.password)) + buffer.WriteString(",token:") + fmt.Fprintf(buffer, "%q", secret.Token(c.token)) + if c.sourceInfo != "" { + buffer.WriteString(",from:") + fmt.Fprintf(buffer, "%q", c.sourceInfo) + } + buffer.WriteByte(')') + return buffer.String() }
internal/credentials/unauthenticated_error.go+99 −0 added@@ -0,0 +1,99 @@ +package credentials + +import ( + "bytes" + "fmt" + "reflect" + "strconv" + + "github.com/ydb-platform/ydb-go-sdk/v3/internal/allocator" + "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors" +) + +type unauthenticatedErrorOption interface { + applyUnauthenticatedErrorOption(buffer *bytes.Buffer) +} + +var ( + _ unauthenticatedErrorOption = nodeIDUnauthenticatedErrorOption(0) + _ unauthenticatedErrorOption = addressUnauthenticatedErrorOption("") +) + +type addressUnauthenticatedErrorOption string + +func (address addressUnauthenticatedErrorOption) applyUnauthenticatedErrorOption(buffer *bytes.Buffer) { + buffer.WriteString("address:") + fmt.Fprintf(buffer, "%q", address) +} + +func WithAddress(address string) addressUnauthenticatedErrorOption { + return addressUnauthenticatedErrorOption(address) +} + +type endpointUnauthenticatedErrorOption string + +func (endpoint endpointUnauthenticatedErrorOption) applyUnauthenticatedErrorOption(buffer *bytes.Buffer) { + buffer.WriteString("endpoint:") + fmt.Fprintf(buffer, "%q", endpoint) +} + +func WithEndpoint(endpoint string) endpointUnauthenticatedErrorOption { + return endpointUnauthenticatedErrorOption(endpoint) +} + +type databaseUnauthenticatedErrorOption string + +func (address databaseUnauthenticatedErrorOption) applyUnauthenticatedErrorOption(buffer *bytes.Buffer) { + buffer.WriteString("database:") + fmt.Fprintf(buffer, "%q", address) +} + +func WithDatabase(database string) databaseUnauthenticatedErrorOption { + return databaseUnauthenticatedErrorOption(database) +} + +type nodeIDUnauthenticatedErrorOption uint32 + +func (id nodeIDUnauthenticatedErrorOption) applyUnauthenticatedErrorOption(buffer *bytes.Buffer) { + buffer.WriteString("nodeID:") + buffer.WriteString(strconv.FormatUint(uint64(id), 10)) +} + +func WithNodeID(id uint32) unauthenticatedErrorOption { + return nodeIDUnauthenticatedErrorOption(id) +} + +type credentialsUnauthenticatedErrorOption struct { + credentials Credentials +} + +func (opt credentialsUnauthenticatedErrorOption) applyUnauthenticatedErrorOption(buffer *bytes.Buffer) { + buffer.WriteString("credentials:") + if stringer, has := opt.credentials.(fmt.Stringer); has { + fmt.Fprintf(buffer, "%q", stringer.String()) + } else { + t := reflect.TypeOf(opt.credentials) + fmt.Fprintf(buffer, "%q", t.PkgPath()+"."+t.Name()) + } +} + +func WithCredentials(credentials Credentials) credentialsUnauthenticatedErrorOption { + return credentialsUnauthenticatedErrorOption{ + credentials: credentials, + } +} + +func UnauthenticatedError(msg string, err error, opts ...unauthenticatedErrorOption) error { + buffer := allocator.Buffers.Get() + defer allocator.Buffers.Put(buffer) + buffer.WriteString(msg) + buffer.WriteString(" (") + for i, opt := range opts { + if i != 0 { + buffer.WriteString(",") + } + opt.applyUnauthenticatedErrorOption(buffer) + } + buffer.WriteString("): %w") + return xerrors.WithStackTrace(fmt.Errorf(buffer.String(), err), xerrors.WithSkipDepth(1)) +}
internal/credentials/unauthenticated_error_test.go+159 −0 added@@ -0,0 +1,159 @@ +package credentials + +import ( + "context" + "errors" + "testing" + + "github.com/stretchr/testify/require" +) + +var _ Credentials = customCredentials{} + +type customCredentials struct { + token string +} + +func (c customCredentials) Token(ctx context.Context) (string, error) { + return c.token, nil +} + +func TestUnauthenticatedError(t *testing.T) { + for _, tt := range []struct { + err error + errorString string + }{ + { + err: UnauthenticatedError( + "something went wrong", + errors.New("test"), + WithEndpoint("grps://localhost:2135"), + WithDatabase("/local"), + WithCredentials(NewAnonymousCredentials(WithSourceInfo(""))), + ), + errorString: "something went wrong (" + + "endpoint:\"grps://localhost:2135\"," + + "database:\"/local\"," + + "credentials:\"Anonymous()\"" + + "): test " + + "at `github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials.TestUnauthenticatedError(unauthenticated_error_test.go:27)`", //nolint:lll + }, + { + err: UnauthenticatedError( + "something went wrong", + errors.New("test"), + WithEndpoint("grps://localhost:2135"), + WithDatabase("/local"), + WithCredentials(NewAnonymousCredentials(WithSourceInfo(t.Name()))), + ), + errorString: "something went wrong (" + + "endpoint:\"grps://localhost:2135\"," + + "database:\"/local\"," + + "credentials:\"Anonymous(from:\\\"TestUnauthenticatedError\\\")\"" + + "): test " + + "at `github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials.TestUnauthenticatedError(unauthenticated_error_test.go:42)`", //nolint:lll + }, + { + err: UnauthenticatedError( + "something went wrong", + errors.New("test"), + WithEndpoint("grps://localhost:2135"), + WithDatabase("/local"), + WithCredentials(NewAccessTokenCredentials("SECRET_TOKEN", WithSourceInfo(""))), + ), + errorString: "something went wrong (" + + "endpoint:\"grps://localhost:2135\"," + + "database:\"/local\"," + + "credentials:\"AccessToken(token:\\\"****(CRC-32c: 9B7801F4)\\\")\"" + + "): test " + + "at `github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials.TestUnauthenticatedError(unauthenticated_error_test.go:57)`", //nolint:lll + }, + { + err: UnauthenticatedError( + "something went wrong", + errors.New("test"), + WithEndpoint("grps://localhost:2135"), + WithDatabase("/local"), + WithCredentials(NewAccessTokenCredentials("SECRET_TOKEN", WithSourceInfo(t.Name()))), + ), + errorString: "something went wrong (" + + "endpoint:\"grps://localhost:2135\"," + + "database:\"/local\"," + + "credentials:\"AccessToken(token:\\\"****(CRC-32c: 9B7801F4)\\\",from:\\\"TestUnauthenticatedError\\\")\"" + //nolint:lll + "): test " + + "at `github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials.TestUnauthenticatedError(unauthenticated_error_test.go:72)`", //nolint:lll + }, + { + err: UnauthenticatedError( + "something went wrong", + errors.New("test"), + WithEndpoint("grps://localhost:2135"), + WithDatabase("/local"), + WithCredentials( + NewStaticCredentials("USER", "SECRET_PASSWORD", "auth.endpoint:2135", + WithSourceInfo(""), + ), + ), + ), + errorString: "something went wrong (" + + "endpoint:\"grps://localhost:2135\"," + + "database:\"/local\"," + + "credentials:\"Static(user:\\\"USER\\\",password:\\\"SEC**********RD\\\",token:\\\"****(CRC-32c: 00000000)\\\")\"" + //nolint:lll + "): test " + + "at `github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials.TestUnauthenticatedError(unauthenticated_error_test.go:87)`", //nolint:lll + }, + { + err: UnauthenticatedError( + "something went wrong", + errors.New("test"), + WithEndpoint("grps://localhost:2135"), + WithDatabase("/local"), + WithCredentials( + NewStaticCredentials("USER", "SECRET_PASSWORD", "auth.endpoint:2135", + WithSourceInfo(t.Name()), + ), + ), + ), + errorString: "something went wrong (" + + "endpoint:\"grps://localhost:2135\"," + + "database:\"/local\"," + + "credentials:\"Static(user:\\\"USER\\\",password:\\\"SEC**********RD\\\",token:\\\"****(CRC-32c: 00000000)\\\",from:\\\"TestUnauthenticatedError\\\")\"" + //nolint:lll + "): test " + + "at `github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials.TestUnauthenticatedError(unauthenticated_error_test.go:106)`", //nolint:lll + }, + { + err: UnauthenticatedError( + "something went wrong", + errors.New("test"), + WithEndpoint("grps://localhost:2135"), + WithDatabase("/local"), + WithCredentials(customCredentials{token: "SECRET_TOKEN"}), + ), + errorString: "something went wrong (" + + "endpoint:\"grps://localhost:2135\"," + + "database:\"/local\"," + + "credentials:\"github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials.customCredentials\"" + + "): test " + + "at `github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials.TestUnauthenticatedError(unauthenticated_error_test.go:125)`", //nolint:lll + }, + { + err: UnauthenticatedError( + "something went wrong", + errors.New("test"), + WithEndpoint("grps://localhost:2135"), + WithDatabase("/local"), + WithCredentials(NewAnonymousCredentials(WithSourceInfo(""))), + ), + errorString: "something went wrong (" + + "endpoint:\"grps://localhost:2135\"," + + "database:\"/local\"," + + "credentials:\"Anonymous()\"" + + "): test " + + "at `github.com/ydb-platform/ydb-go-sdk/v3/internal/credentials.TestUnauthenticatedError(unauthenticated_error_test.go:140)`", //nolint:lll + }, + } { + t.Run("", func(t *testing.T) { + require.Equal(t, tt.errorString, tt.err.Error()) + }) + } +}
tests/integration/database_sql_static_credentials_test.go+2 −2 modified@@ -61,7 +61,7 @@ func TestDatabaseSqlStaticCredentials(t *testing.T) { ydb.WithCredentials(credentials.NewStaticCredentials(u.User.Username(), func() string { password, _ := u.User.Password() return password - }(), u.Host, func() grpc.DialOption { + }(), u.Host, credentials.WithGrpcDialOptions(func() grpc.DialOption { if u.Scheme == "grpcs" { //nolint:goconst transportCredentials, transportCredentialsErr := grpcCredentials.NewClientTLSFromFile( os.Getenv("YDB_SSL_ROOT_CERTIFICATES_FILE"), u.Hostname(), @@ -72,7 +72,7 @@ func TestDatabaseSqlStaticCredentials(t *testing.T) { return grpc.WithTransportCredentials(transportCredentials) } return grpc.WithTransportCredentials(insecure.NewCredentials()) - }())), + }()))), ) require.NoError(t, err)
tests/integration/static_credentials_test.go+2 −2 modified@@ -45,7 +45,7 @@ func TestStaticCredentials(t *testing.T) { staticCredentials := credentials.NewStaticCredentials(u.User.Username(), func() string { password, _ := u.User.Password() return password - }(), u.Host, func() grpc.DialOption { + }(), u.Host, credentials.WithGrpcDialOptions(func() grpc.DialOption { if u.Scheme == "grpcs" { transportCredentials, transportCredentialsErr := grpcCredentials.NewClientTLSFromFile( os.Getenv("YDB_SSL_ROOT_CERTIFICATES_FILE"), u.Hostname(), @@ -56,7 +56,7 @@ func TestStaticCredentials(t *testing.T) { return grpc.WithTransportCredentials(transportCredentials) } return grpc.WithTransportCredentials(insecure.NewCredentials()) - }()) + }())) token, err := staticCredentials.Token(ctx) require.NoError(t, err)
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-q24m-6h38-5xj8ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-45825ghsaADVISORY
- github.com/ydb-platform/ydb-go-sdk/blob/master/credentials/credentials.goghsax_refsource_MISCWEB
- github.com/ydb-platform/ydb-go-sdk/blob/v3.48.6/internal/balancer/balancer.goghsax_refsource_MISCWEB
- github.com/ydb-platform/ydb-go-sdk/commit/a0d92057c4e1bbdc5e85ae8d649edb0232b8fd4cghsaWEB
- github.com/ydb-platform/ydb-go-sdk/pull/859ghsax_refsource_MISCWEB
- github.com/ydb-platform/ydb-go-sdk/security/advisories/GHSA-q24m-6h38-5xj8ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.