mirror of
https://github.com/redis/go-redis.git
synced 2025-04-17 20:17:02 +03:00
fix: handle network error on SETINFO (#3295) (CVE-2025-29923)
* fix: handle network error on SETINFO This fix addresses potential out of order responses as described in `CVE-2025-29923` * fix: deprecate DisableIndentity and introduce DisableIdentity Both options will work before V10. In v10 DisableIndentity will be dropped. The preferred flag to use is `DisableIdentity`.
This commit is contained in:
parent
0858ed24e6
commit
b413caa309
@ -169,16 +169,18 @@ By default, go-redis automatically sends the client library name and version dur
|
|||||||
|
|
||||||
#### Disabling Identity Verification
|
#### Disabling Identity Verification
|
||||||
|
|
||||||
When connection identity verification is not required or needs to be explicitly disabled, a `DisableIndentity` configuration option exists. In V10 of this library, `DisableIndentity` will become `DisableIdentity` in order to fix the associated typo.
|
When connection identity verification is not required or needs to be explicitly disabled, a `DisableIdentity` configuration option exists.
|
||||||
|
Initially there was a typo and the option was named `DisableIndentity` instead of `DisableIdentity`. The misspelled option is marked as Deprecated and will be removed in V10 of this library.
|
||||||
|
Although both options will work at the moment, the correct option is `DisableIdentity`. The deprecated option will be removed in V10 of this library, so please use the correct option name to avoid any issues.
|
||||||
|
|
||||||
To disable verification, set the `DisableIndentity` option to `true` in the Redis client options:
|
To disable verification, set the `DisableIdentity` option to `true` in the Redis client options:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
rdb := redis.NewClient(&redis.Options{
|
rdb := redis.NewClient(&redis.Options{
|
||||||
Addr: "localhost:6379",
|
Addr: "localhost:6379",
|
||||||
Password: "",
|
Password: "",
|
||||||
DB: 0,
|
DB: 0,
|
||||||
DisableIndentity: true, // Disable set-info on connect
|
DisableIdentity: true, // Disable set-info on connect
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ func NewClientStub(resp []byte) *ClientStub {
|
|||||||
Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||||
return stub.stubConn(initHello), nil
|
return stub.stubConn(initHello), nil
|
||||||
},
|
},
|
||||||
DisableIndentity: true,
|
DisableIdentity: true,
|
||||||
})
|
})
|
||||||
return stub
|
return stub
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ func NewClusterClientStub(resp []byte) *ClientStub {
|
|||||||
Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||||
return stub.stubConn(initHello), nil
|
return stub.stubConn(initHello), nil
|
||||||
},
|
},
|
||||||
DisableIndentity: true,
|
DisableIdentity: true,
|
||||||
|
|
||||||
ClusterSlots: func(_ context.Context) ([]ClusterSlot, error) {
|
ClusterSlots: func(_ context.Context) ([]ClusterSlot, error) {
|
||||||
return []ClusterSlot{
|
return []ClusterSlot{
|
||||||
|
11
options.go
11
options.go
@ -148,9 +148,18 @@ type Options struct {
|
|||||||
// Enables read only queries on slave/follower nodes.
|
// Enables read only queries on slave/follower nodes.
|
||||||
readOnly bool
|
readOnly bool
|
||||||
|
|
||||||
// Disable set-lib on connect. Default is false.
|
// DisableIndentity - Disable set-lib on connect.
|
||||||
|
//
|
||||||
|
// default: false
|
||||||
|
//
|
||||||
|
// Deprecated: Use DisableIdentity instead.
|
||||||
DisableIndentity bool
|
DisableIndentity bool
|
||||||
|
|
||||||
|
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
|
||||||
|
//
|
||||||
|
// default: false
|
||||||
|
DisableIdentity bool
|
||||||
|
|
||||||
// Add suffix to client name. Default is empty.
|
// Add suffix to client name. Default is empty.
|
||||||
IdentitySuffix string
|
IdentitySuffix string
|
||||||
}
|
}
|
||||||
|
@ -86,8 +86,19 @@ type ClusterOptions struct {
|
|||||||
ConnMaxIdleTime time.Duration
|
ConnMaxIdleTime time.Duration
|
||||||
ConnMaxLifetime time.Duration
|
ConnMaxLifetime time.Duration
|
||||||
|
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
DisableIndentity bool // Disable set-lib on connect. Default is false.
|
|
||||||
|
// DisableIndentity - Disable set-lib on connect.
|
||||||
|
//
|
||||||
|
// default: false
|
||||||
|
//
|
||||||
|
// Deprecated: Use DisableIdentity instead.
|
||||||
|
DisableIndentity bool
|
||||||
|
|
||||||
|
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
|
||||||
|
//
|
||||||
|
// default: false
|
||||||
|
DisableIdentity bool
|
||||||
|
|
||||||
IdentitySuffix string // Add suffix to client name. Default is empty.
|
IdentitySuffix string // Add suffix to client name. Default is empty.
|
||||||
}
|
}
|
||||||
@ -296,7 +307,8 @@ func (opt *ClusterOptions) clientOptions() *Options {
|
|||||||
MaxActiveConns: opt.MaxActiveConns,
|
MaxActiveConns: opt.MaxActiveConns,
|
||||||
ConnMaxIdleTime: opt.ConnMaxIdleTime,
|
ConnMaxIdleTime: opt.ConnMaxIdleTime,
|
||||||
ConnMaxLifetime: opt.ConnMaxLifetime,
|
ConnMaxLifetime: opt.ConnMaxLifetime,
|
||||||
DisableIndentity: opt.DisableIndentity,
|
DisableIdentity: opt.DisableIdentity,
|
||||||
|
DisableIndentity: opt.DisableIdentity,
|
||||||
IdentitySuffix: opt.IdentitySuffix,
|
IdentitySuffix: opt.IdentitySuffix,
|
||||||
TLSConfig: opt.TLSConfig,
|
TLSConfig: opt.TLSConfig,
|
||||||
// If ClusterSlots is populated, then we probably have an artificial
|
// If ClusterSlots is populated, then we probably have an artificial
|
||||||
|
8
redis.go
8
redis.go
@ -345,7 +345,7 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.opt.DisableIndentity {
|
if !c.opt.DisableIdentity && !c.opt.DisableIndentity {
|
||||||
libName := ""
|
libName := ""
|
||||||
libVer := Version()
|
libVer := Version()
|
||||||
if c.opt.IdentitySuffix != "" {
|
if c.opt.IdentitySuffix != "" {
|
||||||
@ -354,7 +354,11 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error {
|
|||||||
p := conn.Pipeline()
|
p := conn.Pipeline()
|
||||||
p.ClientSetInfo(ctx, WithLibraryName(libName))
|
p.ClientSetInfo(ctx, WithLibraryName(libName))
|
||||||
p.ClientSetInfo(ctx, WithLibraryVersion(libVer))
|
p.ClientSetInfo(ctx, WithLibraryVersion(libVer))
|
||||||
_, _ = p.Exec(ctx)
|
// Handle network errors (e.g. timeouts) in CLIENT SETINFO to avoid
|
||||||
|
// out of order responses later on.
|
||||||
|
if _, err = p.Exec(ctx); err != nil && !isRedisError(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.opt.OnConnect != nil {
|
if c.opt.OnConnect != nil {
|
||||||
|
@ -373,6 +373,13 @@ var _ = Describe("Client timeout", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
testTimeout := func() {
|
testTimeout := func() {
|
||||||
|
It("SETINFO timeouts", func() {
|
||||||
|
conn := client.Conn()
|
||||||
|
err := conn.Ping(ctx).Err()
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err.(net.Error).Timeout()).To(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
It("Ping timeouts", func() {
|
It("Ping timeouts", func() {
|
||||||
err := client.Ping(ctx).Err()
|
err := client.Ping(ctx).Err()
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).To(HaveOccurred())
|
||||||
|
13
ring.go
13
ring.go
@ -98,8 +98,18 @@ type RingOptions struct {
|
|||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
Limiter Limiter
|
Limiter Limiter
|
||||||
|
|
||||||
|
// DisableIndentity - Disable set-lib on connect.
|
||||||
|
//
|
||||||
|
// default: false
|
||||||
|
//
|
||||||
|
// Deprecated: Use DisableIdentity instead.
|
||||||
DisableIndentity bool
|
DisableIndentity bool
|
||||||
IdentitySuffix string
|
|
||||||
|
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
|
||||||
|
//
|
||||||
|
// default: false
|
||||||
|
DisableIdentity bool
|
||||||
|
IdentitySuffix string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opt *RingOptions) init() {
|
func (opt *RingOptions) init() {
|
||||||
@ -166,6 +176,7 @@ func (opt *RingOptions) clientOptions() *Options {
|
|||||||
TLSConfig: opt.TLSConfig,
|
TLSConfig: opt.TLSConfig,
|
||||||
Limiter: opt.Limiter,
|
Limiter: opt.Limiter,
|
||||||
|
|
||||||
|
DisableIdentity: opt.DisableIdentity,
|
||||||
DisableIndentity: opt.DisableIndentity,
|
DisableIndentity: opt.DisableIndentity,
|
||||||
IdentitySuffix: opt.IdentitySuffix,
|
IdentitySuffix: opt.IdentitySuffix,
|
||||||
}
|
}
|
||||||
|
16
sentinel.go
16
sentinel.go
@ -80,8 +80,19 @@ type FailoverOptions struct {
|
|||||||
|
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
|
|
||||||
|
// DisableIndentity - Disable set-lib on connect.
|
||||||
|
//
|
||||||
|
// default: false
|
||||||
|
//
|
||||||
|
// Deprecated: Use DisableIdentity instead.
|
||||||
DisableIndentity bool
|
DisableIndentity bool
|
||||||
IdentitySuffix string
|
|
||||||
|
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
|
||||||
|
//
|
||||||
|
// default: false
|
||||||
|
DisableIdentity bool
|
||||||
|
|
||||||
|
IdentitySuffix string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opt *FailoverOptions) clientOptions() *Options {
|
func (opt *FailoverOptions) clientOptions() *Options {
|
||||||
@ -117,6 +128,7 @@ func (opt *FailoverOptions) clientOptions() *Options {
|
|||||||
|
|
||||||
TLSConfig: opt.TLSConfig,
|
TLSConfig: opt.TLSConfig,
|
||||||
|
|
||||||
|
DisableIdentity: opt.DisableIdentity,
|
||||||
DisableIndentity: opt.DisableIndentity,
|
DisableIndentity: opt.DisableIndentity,
|
||||||
IdentitySuffix: opt.IdentitySuffix,
|
IdentitySuffix: opt.IdentitySuffix,
|
||||||
}
|
}
|
||||||
@ -154,6 +166,7 @@ func (opt *FailoverOptions) sentinelOptions(addr string) *Options {
|
|||||||
|
|
||||||
TLSConfig: opt.TLSConfig,
|
TLSConfig: opt.TLSConfig,
|
||||||
|
|
||||||
|
DisableIdentity: opt.DisableIdentity,
|
||||||
DisableIndentity: opt.DisableIndentity,
|
DisableIndentity: opt.DisableIndentity,
|
||||||
IdentitySuffix: opt.IdentitySuffix,
|
IdentitySuffix: opt.IdentitySuffix,
|
||||||
}
|
}
|
||||||
@ -194,6 +207,7 @@ func (opt *FailoverOptions) clusterOptions() *ClusterOptions {
|
|||||||
|
|
||||||
TLSConfig: opt.TLSConfig,
|
TLSConfig: opt.TLSConfig,
|
||||||
|
|
||||||
|
DisableIdentity: opt.DisableIdentity,
|
||||||
DisableIndentity: opt.DisableIndentity,
|
DisableIndentity: opt.DisableIndentity,
|
||||||
IdentitySuffix: opt.IdentitySuffix,
|
IdentitySuffix: opt.IdentitySuffix,
|
||||||
}
|
}
|
||||||
|
17
universal.go
17
universal.go
@ -66,8 +66,19 @@ type UniversalOptions struct {
|
|||||||
|
|
||||||
MasterName string
|
MasterName string
|
||||||
|
|
||||||
|
// DisableIndentity - Disable set-lib on connect.
|
||||||
|
//
|
||||||
|
// default: false
|
||||||
|
//
|
||||||
|
// Deprecated: Use DisableIdentity instead.
|
||||||
DisableIndentity bool
|
DisableIndentity bool
|
||||||
IdentitySuffix string
|
|
||||||
|
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
|
||||||
|
//
|
||||||
|
// default: false
|
||||||
|
DisableIdentity bool
|
||||||
|
|
||||||
|
IdentitySuffix string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cluster returns cluster options created from the universal options.
|
// Cluster returns cluster options created from the universal options.
|
||||||
@ -112,6 +123,7 @@ func (o *UniversalOptions) Cluster() *ClusterOptions {
|
|||||||
|
|
||||||
TLSConfig: o.TLSConfig,
|
TLSConfig: o.TLSConfig,
|
||||||
|
|
||||||
|
DisableIdentity: o.DisableIdentity,
|
||||||
DisableIndentity: o.DisableIndentity,
|
DisableIndentity: o.DisableIndentity,
|
||||||
IdentitySuffix: o.IdentitySuffix,
|
IdentitySuffix: o.IdentitySuffix,
|
||||||
}
|
}
|
||||||
@ -158,6 +170,8 @@ func (o *UniversalOptions) Failover() *FailoverOptions {
|
|||||||
|
|
||||||
TLSConfig: o.TLSConfig,
|
TLSConfig: o.TLSConfig,
|
||||||
|
|
||||||
|
|
||||||
|
DisableIdentity: o.DisableIdentity,
|
||||||
DisableIndentity: o.DisableIndentity,
|
DisableIndentity: o.DisableIndentity,
|
||||||
IdentitySuffix: o.IdentitySuffix,
|
IdentitySuffix: o.IdentitySuffix,
|
||||||
}
|
}
|
||||||
@ -201,6 +215,7 @@ func (o *UniversalOptions) Simple() *Options {
|
|||||||
|
|
||||||
TLSConfig: o.TLSConfig,
|
TLSConfig: o.TLSConfig,
|
||||||
|
|
||||||
|
DisableIdentity: o.DisableIdentity,
|
||||||
DisableIndentity: o.DisableIndentity,
|
DisableIndentity: o.DisableIndentity,
|
||||||
IdentitySuffix: o.IdentitySuffix,
|
IdentitySuffix: o.IdentitySuffix,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user