Skip to content

Commit 8036027

Browse files
committed
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`.
1 parent 2a6c4c2 commit 8036027

9 files changed

+89
-14
lines changed

README.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,18 @@ By default, go-redis automatically sends the client library name and version dur
169169

170170
#### Disabling Identity Verification
171171

172-
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.
172+
When connection identity verification is not required or needs to be explicitly disabled, a `DisableIdentity` configuration option exists.
173+
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.
174+
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.
173175

174-
To disable verification, set the `DisableIndentity` option to `true` in the Redis client options:
176+
To disable verification, set the `DisableIdentity` option to `true` in the Redis client options:
175177

176178
```go
177179
rdb := redis.NewClient(&redis.Options{
178180
Addr: "localhost:6379",
179181
Password: "",
180182
DB: 0,
181-
DisableIndentity: true, // Disable set-info on connect
183+
DisableIdentity: true, // Disable set-info on connect
182184
})
183185
```
184186

bench_decode_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func NewClientStub(resp []byte) *ClientStub {
3030
Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
3131
return stub.stubConn(initHello), nil
3232
},
33-
DisableIndentity: true,
33+
DisableIdentity: true,
3434
})
3535
return stub
3636
}
@@ -46,7 +46,7 @@ func NewClusterClientStub(resp []byte) *ClientStub {
4646
Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
4747
return stub.stubConn(initHello), nil
4848
},
49-
DisableIndentity: true,
49+
DisableIdentity: true,
5050

5151
ClusterSlots: func(_ context.Context) ([]ClusterSlot, error) {
5252
return []ClusterSlot{

options.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,18 @@ type Options struct {
148148
// Enables read only queries on slave/follower nodes.
149149
readOnly bool
150150

151-
// Disable set-lib on connect. Default is false.
151+
// DisableIndentity - Disable set-lib on connect.
152+
//
153+
// default: false
154+
//
155+
// Deprecated: Use DisableIdentity instead.
152156
DisableIndentity bool
153157

158+
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
159+
//
160+
// default: false
161+
DisableIdentity bool
162+
154163
// Add suffix to client name. Default is empty.
155164
IdentitySuffix string
156165
}

osscluster.go

+15-3
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,19 @@ type ClusterOptions struct {
8686
ConnMaxIdleTime time.Duration
8787
ConnMaxLifetime time.Duration
8888

89-
TLSConfig *tls.Config
90-
DisableIndentity bool // Disable set-lib on connect. Default is false.
89+
TLSConfig *tls.Config
90+
91+
// DisableIndentity - Disable set-lib on connect.
92+
//
93+
// default: false
94+
//
95+
// Deprecated: Use DisableIdentity instead.
96+
DisableIndentity bool
97+
98+
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
99+
//
100+
// default: false
101+
DisableIdentity bool
91102

92103
IdentitySuffix string // Add suffix to client name. Default is empty.
93104
}
@@ -296,7 +307,8 @@ func (opt *ClusterOptions) clientOptions() *Options {
296307
MaxActiveConns: opt.MaxActiveConns,
297308
ConnMaxIdleTime: opt.ConnMaxIdleTime,
298309
ConnMaxLifetime: opt.ConnMaxLifetime,
299-
DisableIndentity: opt.DisableIndentity,
310+
DisableIdentity: opt.DisableIdentity,
311+
DisableIndentity: opt.DisableIdentity,
300312
IdentitySuffix: opt.IdentitySuffix,
301313
TLSConfig: opt.TLSConfig,
302314
// If ClusterSlots is populated, then we probably have an artificial

redis.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error {
345345
return err
346346
}
347347

348-
if !c.opt.DisableIndentity {
348+
if !c.opt.DisableIdentity && !c.opt.DisableIndentity {
349349
libName := ""
350350
libVer := Version()
351351
if c.opt.IdentitySuffix != "" {
@@ -354,7 +354,11 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error {
354354
p := conn.Pipeline()
355355
p.ClientSetInfo(ctx, WithLibraryName(libName))
356356
p.ClientSetInfo(ctx, WithLibraryVersion(libVer))
357-
_, _ = p.Exec(ctx)
357+
// Handle network errors (e.g. timeouts) in CLIENT SETINFO to avoid
358+
// out of order responses later on.
359+
if _, err = p.Exec(ctx); err != nil && !isRedisError(err) {
360+
return err
361+
}
358362
}
359363

360364
if c.opt.OnConnect != nil {

redis_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,13 @@ var _ = Describe("Client timeout", func() {
373373
})
374374

375375
testTimeout := func() {
376+
It("SETINFO timeouts", func() {
377+
conn := client.Conn()
378+
err := conn.Ping(ctx).Err()
379+
Expect(err).To(HaveOccurred())
380+
Expect(err.(net.Error).Timeout()).To(BeTrue())
381+
})
382+
376383
It("Ping timeouts", func() {
377384
err := client.Ping(ctx).Err()
378385
Expect(err).To(HaveOccurred())

ring.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,18 @@ type RingOptions struct {
9898
TLSConfig *tls.Config
9999
Limiter Limiter
100100

101+
// DisableIndentity - Disable set-lib on connect.
102+
//
103+
// default: false
104+
//
105+
// Deprecated: Use DisableIdentity instead.
101106
DisableIndentity bool
102-
IdentitySuffix string
107+
108+
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
109+
//
110+
// default: false
111+
DisableIdentity bool
112+
IdentitySuffix string
103113
}
104114

105115
func (opt *RingOptions) init() {
@@ -166,6 +176,7 @@ func (opt *RingOptions) clientOptions() *Options {
166176
TLSConfig: opt.TLSConfig,
167177
Limiter: opt.Limiter,
168178

179+
DisableIdentity: opt.DisableIdentity,
169180
DisableIndentity: opt.DisableIndentity,
170181
IdentitySuffix: opt.IdentitySuffix,
171182
}

sentinel.go

+15-1
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,19 @@ type FailoverOptions struct {
8080

8181
TLSConfig *tls.Config
8282

83+
// DisableIndentity - Disable set-lib on connect.
84+
//
85+
// default: false
86+
//
87+
// Deprecated: Use DisableIdentity instead.
8388
DisableIndentity bool
84-
IdentitySuffix string
89+
90+
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
91+
//
92+
// default: false
93+
DisableIdentity bool
94+
95+
IdentitySuffix string
8596
}
8697

8798
func (opt *FailoverOptions) clientOptions() *Options {
@@ -117,6 +128,7 @@ func (opt *FailoverOptions) clientOptions() *Options {
117128

118129
TLSConfig: opt.TLSConfig,
119130

131+
DisableIdentity: opt.DisableIdentity,
120132
DisableIndentity: opt.DisableIndentity,
121133
IdentitySuffix: opt.IdentitySuffix,
122134
}
@@ -154,6 +166,7 @@ func (opt *FailoverOptions) sentinelOptions(addr string) *Options {
154166

155167
TLSConfig: opt.TLSConfig,
156168

169+
DisableIdentity: opt.DisableIdentity,
157170
DisableIndentity: opt.DisableIndentity,
158171
IdentitySuffix: opt.IdentitySuffix,
159172
}
@@ -194,6 +207,7 @@ func (opt *FailoverOptions) clusterOptions() *ClusterOptions {
194207

195208
TLSConfig: opt.TLSConfig,
196209

210+
DisableIdentity: opt.DisableIdentity,
197211
DisableIndentity: opt.DisableIndentity,
198212
IdentitySuffix: opt.IdentitySuffix,
199213
}

universal.go

+17-1
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,19 @@ type UniversalOptions struct {
6666

6767
MasterName string
6868

69+
// DisableIndentity - Disable set-lib on connect.
70+
//
71+
// default: false
72+
//
73+
// Deprecated: Use DisableIdentity instead.
6974
DisableIndentity bool
70-
IdentitySuffix string
75+
76+
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
77+
//
78+
// default: false
79+
DisableIdentity bool
80+
81+
IdentitySuffix string
7182
}
7283

7384
// Cluster returns cluster options created from the universal options.
@@ -112,6 +123,7 @@ func (o *UniversalOptions) Cluster() *ClusterOptions {
112123

113124
TLSConfig: o.TLSConfig,
114125

126+
DisableIdentity: o.DisableIdentity,
115127
DisableIndentity: o.DisableIndentity,
116128
IdentitySuffix: o.IdentitySuffix,
117129
}
@@ -158,6 +170,9 @@ func (o *UniversalOptions) Failover() *FailoverOptions {
158170

159171
TLSConfig: o.TLSConfig,
160172

173+
ReplicaOnly: o.ReadOnly,
174+
175+
DisableIdentity: o.DisableIdentity,
161176
DisableIndentity: o.DisableIndentity,
162177
IdentitySuffix: o.IdentitySuffix,
163178
}
@@ -201,6 +216,7 @@ func (o *UniversalOptions) Simple() *Options {
201216

202217
TLSConfig: o.TLSConfig,
203218

219+
DisableIdentity: o.DisableIdentity,
204220
DisableIndentity: o.DisableIndentity,
205221
IdentitySuffix: o.IdentitySuffix,
206222
}

0 commit comments

Comments
 (0)