Skip to content

Commit aa876af

Browse files
committed
fix: add mandatory space before negative numbers to resolve CVE-2024-44905
The fix was adapted from uptrace/bun@8067a8f
1 parent 6e60d54 commit aa876af

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

orm/format_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,30 @@ var formatTests = []formatTest{
146146
paramsMap: paramsMap{"string": "my_value"},
147147
wanted: "?string",
148148
},
149+
150+
{
151+
q: "select 1-?0, 1.0-?1, 1.0-?2",
152+
params: params{int64(-1), float64(-1.5), math.Inf(-1)},
153+
wanted: "select 1- -1, 1.0- -1.5, 1.0-'-Infinity'",
154+
},
155+
{
156+
q: "select 1+?0, 1.0+?1",
157+
params: params{int64(-1), float64(-1.5)},
158+
wanted: "select 1+-1, 1.0+-1.5",
159+
},
160+
{
161+
q: "select 1-?0, ?1",
162+
params: params{int64(-1), "foo\n;\nSELECT * FROM passwords;--"},
163+
// Without a space before the negative number, the first line ends in a comment
164+
wanted: `select 1- -1, 'foo
165+
;
166+
SELECT * FROM passwords;--'`,
167+
},
168+
{
169+
q: "?0",
170+
params: params{int64(-1)},
171+
wanted: "-1",
172+
},
149173
}
150174

151175
func TestFormatQuery(t *testing.T) {

types/append.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ func Append(b []byte, v interface{}, flags int) []byte {
1717
case bool:
1818
return appendBool(b, v)
1919
case int32:
20-
return strconv.AppendInt(b, int64(v), 10)
20+
return appendInt(b, int64(v))
2121
case int64:
22-
return strconv.AppendInt(b, v, 10)
22+
return appendInt(b, v)
2323
case int:
24-
return strconv.AppendInt(b, int64(v), 10)
24+
return appendInt(b, int64(v))
2525
case float32:
2626
return appendFloat(b, float64(v), flags, 32)
2727
case float64:
@@ -60,6 +60,15 @@ func appendBool(dst []byte, v bool) []byte {
6060
return append(dst, "FALSE"...)
6161
}
6262

63+
func appendInt(dst []byte, v int64) []byte {
64+
// To avoid accidental comments which can lead to SQL injection, put a space before
65+
// negative numbers immediately following a minus sign.
66+
if v < 0 && len(dst) > 0 && dst[len(dst)-1] == '-' {
67+
dst = append(dst, ' ')
68+
}
69+
return strconv.AppendInt(dst, v, 10)
70+
}
71+
6372
func appendFloat(dst []byte, v float64, flags int, bitSize int) []byte {
6473
if hasFlag(flags, arrayFlag) {
6574
return appendFloat2(dst, v, flags)
@@ -80,8 +89,18 @@ func appendFloat(dst []byte, v float64, flags int, bitSize int) []byte {
8089
if hasFlag(flags, quoteFlag) {
8190
return append(dst, "'-Infinity'"...)
8291
}
92+
// To avoid accidental comments which can lead to SQL injection, put a space before
93+
// negative numbers immediately following a minus sign.
94+
if v < 0 && len(dst) > 0 && dst[len(dst)-1] == '-' {
95+
dst = append(dst, ' ')
96+
}
8397
return append(dst, "-Infinity"...)
8498
default:
99+
// To avoid accidental comments which can lead to SQL injection, put a space before
100+
// negative numbers immediately following a minus sign.
101+
if v < 0 && len(dst) > 0 && dst[len(dst)-1] == '-' {
102+
dst = append(dst, ' ')
103+
}
85104
return strconv.AppendFloat(dst, v, 'f', -1, bitSize)
86105
}
87106
}

types/append_value.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type AppenderFunc func([]byte, reflect.Value, int) []byte
2424

2525
var appenders []AppenderFunc
2626

27-
//nolint
27+
// nolint
2828
func init() {
2929
appenders = []AppenderFunc{
3030
reflect.Bool: appendBoolValue,
@@ -148,7 +148,7 @@ func appendBoolValue(b []byte, v reflect.Value, _ int) []byte {
148148
}
149149

150150
func appendIntValue(b []byte, v reflect.Value, _ int) []byte {
151-
return strconv.AppendInt(b, v.Int(), 10)
151+
return appendInt(b, v.Int())
152152
}
153153

154154
func appendUintValue(b []byte, v reflect.Value, _ int) []byte {

0 commit comments

Comments
 (0)