Skip to content

Commit d236865

Browse files
authored
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 74d4f08 commit d236865

9 files changed

+104
-28
lines changed

README.md

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

179179
#### Disabling Identity Verification
180180

181-
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.
181+
When connection identity verification is not required or needs to be explicitly disabled, a `DisableIdentity` configuration option exists.
182+
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.
183+
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.
182184

183-
To disable verification, set the `DisableIndentity` option to `true` in the Redis client options:
185+
To disable verification, set the `DisableIdentity` option to `true` in the Redis client options:
184186

185187
```go
186188
rdb := redis.NewClient(&redis.Options{
187189
Addr: "localhost:6379",
188190
Password: "",
189191
DB: 0,
190-
DisableIndentity: true, // Disable set-info on connect
192+
DisableIdentity: true, // Disable set-info on connect
191193
})
192194
```
193195

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
@@ -90,8 +90,19 @@ type ClusterOptions struct {
9090
ConnMaxIdleTime time.Duration
9191
ConnMaxLifetime time.Duration
9292

93-
TLSConfig *tls.Config
94-
DisableIndentity bool // Disable set-lib on connect. Default is false.
93+
TLSConfig *tls.Config
94+
95+
// DisableIndentity - Disable set-lib on connect.
96+
//
97+
// default: false
98+
//
99+
// Deprecated: Use DisableIdentity instead.
100+
DisableIndentity bool
101+
102+
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
103+
//
104+
// default: false
105+
DisableIdentity bool
95106

96107
IdentitySuffix string // Add suffix to client name. Default is empty.
97108

@@ -303,7 +314,8 @@ func (opt *ClusterOptions) clientOptions() *Options {
303314
MaxActiveConns: opt.MaxActiveConns,
304315
ConnMaxIdleTime: opt.ConnMaxIdleTime,
305316
ConnMaxLifetime: opt.ConnMaxLifetime,
306-
DisableIndentity: opt.DisableIndentity,
317+
DisableIdentity: opt.DisableIdentity,
318+
DisableIndentity: opt.DisableIdentity,
307319
IdentitySuffix: opt.IdentitySuffix,
308320
TLSConfig: opt.TLSConfig,
309321
// If ClusterSlots is populated, then we probably have an artificial

redis.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error {
350350
return err
351351
}
352352

353-
if !c.opt.DisableIndentity {
353+
if !c.opt.DisableIdentity && !c.opt.DisableIndentity {
354354
libName := ""
355355
libVer := Version()
356356
if c.opt.IdentitySuffix != "" {
@@ -359,7 +359,11 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error {
359359
p := conn.Pipeline()
360360
p.ClientSetInfo(ctx, WithLibraryName(libName))
361361
p.ClientSetInfo(ctx, WithLibraryVersion(libVer))
362-
_, _ = p.Exec(ctx)
362+
// Handle network errors (e.g. timeouts) in CLIENT SETINFO to avoid
363+
// out of order responses later on.
364+
if _, err = p.Exec(ctx); err != nil && !isRedisError(err) {
365+
return err
366+
}
363367
}
364368

365369
if c.opt.OnConnect != nil {

redis_test.go

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

398398
testTimeout := func() {
399+
It("SETINFO timeouts", func() {
400+
conn := client.Conn()
401+
err := conn.Ping(ctx).Err()
402+
Expect(err).To(HaveOccurred())
403+
Expect(err.(net.Error).Timeout()).To(BeTrue())
404+
})
405+
399406
It("Ping timeouts", func() {
400407
err := client.Ping(ctx).Err()
401408
Expect(err).To(HaveOccurred())

ring.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,19 @@ 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
103-
UnstableResp3 bool
107+
108+
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
109+
//
110+
// default: false
111+
DisableIdentity bool
112+
IdentitySuffix string
113+
UnstableResp3 bool
104114
}
105115

106116
func (opt *RingOptions) init() {
@@ -167,9 +177,11 @@ func (opt *RingOptions) clientOptions() *Options {
167177
TLSConfig: opt.TLSConfig,
168178
Limiter: opt.Limiter,
169179

180+
DisableIdentity: opt.DisableIdentity,
170181
DisableIndentity: opt.DisableIndentity,
171-
IdentitySuffix: opt.IdentitySuffix,
172-
UnstableResp3: opt.UnstableResp3,
182+
183+
IdentitySuffix: opt.IdentitySuffix,
184+
UnstableResp3: opt.UnstableResp3,
173185
}
174186
}
175187

sentinel.go

+24-7
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,20 @@ 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
85-
UnstableResp3 bool
89+
90+
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
91+
//
92+
// default: false
93+
DisableIdentity bool
94+
95+
IdentitySuffix string
96+
UnstableResp3 bool
8697
}
8798

8899
func (opt *FailoverOptions) clientOptions() *Options {
@@ -118,9 +129,11 @@ func (opt *FailoverOptions) clientOptions() *Options {
118129

119130
TLSConfig: opt.TLSConfig,
120131

132+
DisableIdentity: opt.DisableIdentity,
121133
DisableIndentity: opt.DisableIndentity,
122-
IdentitySuffix: opt.IdentitySuffix,
123-
UnstableResp3: opt.UnstableResp3,
134+
135+
IdentitySuffix: opt.IdentitySuffix,
136+
UnstableResp3: opt.UnstableResp3,
124137
}
125138
}
126139

@@ -156,9 +169,11 @@ func (opt *FailoverOptions) sentinelOptions(addr string) *Options {
156169

157170
TLSConfig: opt.TLSConfig,
158171

172+
DisableIdentity: opt.DisableIdentity,
159173
DisableIndentity: opt.DisableIndentity,
160-
IdentitySuffix: opt.IdentitySuffix,
161-
UnstableResp3: opt.UnstableResp3,
174+
175+
IdentitySuffix: opt.IdentitySuffix,
176+
UnstableResp3: opt.UnstableResp3,
162177
}
163178
}
164179

@@ -197,8 +212,10 @@ func (opt *FailoverOptions) clusterOptions() *ClusterOptions {
197212

198213
TLSConfig: opt.TLSConfig,
199214

215+
DisableIdentity: opt.DisableIdentity,
200216
DisableIndentity: opt.DisableIndentity,
201-
IdentitySuffix: opt.IdentitySuffix,
217+
218+
IdentitySuffix: opt.IdentitySuffix,
202219
}
203220
}
204221

universal.go

+19-6
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,24 @@ type UniversalOptions struct {
6161
RouteByLatency bool
6262
RouteRandomly bool
6363

64-
// The sentinel master name.
65-
// Only failover clients.
66-
64+
// MasterName is the sentinel master name.
65+
// Only for failover clients.
6766
MasterName string
6867

68+
// DisableIndentity - Disable set-lib on connect.
69+
//
70+
// default: false
71+
//
72+
// Deprecated: Use DisableIdentity instead.
6973
DisableIndentity bool
70-
IdentitySuffix string
71-
UnstableResp3 bool
74+
75+
// DisableIdentity is used to disable CLIENT SETINFO command on connect.
76+
//
77+
// default: false
78+
DisableIdentity bool
79+
80+
IdentitySuffix string
81+
UnstableResp3 bool
7282

7383
// IsClusterMode can be used when only one Addrs is provided (e.g. Elasticache supports setting up cluster mode with configuration endpoint).
7484
IsClusterMode bool
@@ -116,6 +126,7 @@ func (o *UniversalOptions) Cluster() *ClusterOptions {
116126

117127
TLSConfig: o.TLSConfig,
118128

129+
DisableIdentity: o.DisableIdentity,
119130
DisableIndentity: o.DisableIndentity,
120131
IdentitySuffix: o.IdentitySuffix,
121132
UnstableResp3: o.UnstableResp3,
@@ -163,8 +174,9 @@ func (o *UniversalOptions) Failover() *FailoverOptions {
163174

164175
TLSConfig: o.TLSConfig,
165176

166-
ReplicaOnly: o.ReadOnly,
177+
ReplicaOnly: o.ReadOnly,
167178

179+
DisableIdentity: o.DisableIdentity,
168180
DisableIndentity: o.DisableIndentity,
169181
IdentitySuffix: o.IdentitySuffix,
170182
UnstableResp3: o.UnstableResp3,
@@ -209,6 +221,7 @@ func (o *UniversalOptions) Simple() *Options {
209221

210222
TLSConfig: o.TLSConfig,
211223

224+
DisableIdentity: o.DisableIdentity,
212225
DisableIndentity: o.DisableIndentity,
213226
IdentitySuffix: o.IdentitySuffix,
214227
UnstableResp3: o.UnstableResp3,

0 commit comments

Comments
 (0)