Skip to content

Commit 83950fa

Browse files
authored
Merge pull request #41 from trimble-oss/security_updates_2.6
Potential fix for code scanning alert no. 231: Incorrect conversion between integer types
2 parents 62d5ce0 + 4b396bb commit 83950fa

File tree

3 files changed

+57
-35
lines changed

3 files changed

+57
-35
lines changed

sql/analyzer/analyzer.go

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -294,63 +294,74 @@ func (a *Analyzer) Log(msg string, args ...interface{}) {
294294
if a != nil && a.Debug {
295295
if len(a.contextStack) > 0 {
296296
ctx := strings.Join(a.contextStack, "/")
297-
log.Infof("%s: "+msg, append([]interface{}{ctx}, sanitizeArguments(args)...)...)
297+
sanitizedArgs := sanitizeArguments(args)
298+
log.Infof("%s: "+msg, append([]interface{}{ctx}, sanitizedArgs...)...)
298299
} else {
299-
log.Infof(msg, sanitizeArguments(args)...)
300+
sanitizedArgs := sanitizeArguments(args)
301+
log.Infof(msg, sanitizedArgs...)
300302
}
301303
}
302304
}
303305

304306
func sanitizeArguments(args []interface{}) []interface{} {
307+
sanitizedArgs := make([]interface{}, len(args))
305308
for i, arg := range args {
306309
switch v := arg.(type) {
307310
case string:
308311
if isSensitiveString(v) {
309-
args[i] = "[REDACTED]"
312+
sanitizedArgs[i] = "[REDACTED]"
313+
} else {
314+
sanitizedArgs[i] = v
310315
}
311316
case map[string]interface{}:
312-
args[i] = sanitizeMap(v)
317+
sanitizedArgs[i] = sanitizeMap(v)
313318
case []interface{}:
314-
args[i] = sanitizeArguments(v)
319+
sanitizedArgs[i] = sanitizeArguments(v)
315320
case plan.AuthenticationMysqlNativePassword:
316-
args[i] = "[PASSWORD_REDACTED]"
321+
sanitizedArgs[i] = "[PASSWORD_REDACTED]"
317322
default:
318323
// Use reflection to handle structs and pointers to structs
319324
rv := reflect.ValueOf(arg)
320325
if rv.Kind() == reflect.Ptr {
321326
rv = rv.Elem()
322327
if rv.Kind() == reflect.Struct {
323-
args[i] = sanitizeStruct(rv)
328+
sanitizedArgs[i] = sanitizeStruct(rv)
324329
continue
325330
}
326331
}
327332
if rv.Kind() == reflect.Struct {
328-
args[i] = sanitizeStruct(rv)
333+
sanitizedArgs[i] = sanitizeStruct(rv)
329334
} else if rv.Kind() == reflect.Slice {
330335
// Recursively sanitize slice elements
331336
slice := make([]interface{}, rv.Len())
332337
for j := 0; j < rv.Len(); j++ {
333338
slice[j] = sanitizeArguments([]interface{}{rv.Index(j).Interface()})[0]
334339
}
335-
args[i] = slice
340+
sanitizedArgs[i] = slice
336341
} else if rv.Kind() == reflect.Map {
337342
// Recursively sanitize map values
338343
mapSanitized := make(map[interface{}]interface{})
339344
for _, key := range rv.MapKeys() {
340345
val := rv.MapIndex(key).Interface()
341-
if isSensitiveString(fmt.Sprintf("%v", key.Interface())) || isSensitive(val) {
346+
keyStr := fmt.Sprintf("%v", key.Interface())
347+
if isSensitiveString(keyStr) || isSensitive(val) {
342348
mapSanitized[key.Interface()] = "[REDACTED]"
343349
} else {
344350
mapSanitized[key.Interface()] = sanitizeArguments([]interface{}{val})[0]
345351
}
346352
}
347-
args[i] = mapSanitized
353+
sanitizedArgs[i] = mapSanitized
348354
} else {
349-
args[i] = "[REDACTED]"
355+
// Catch-all for unhandled types
356+
if strVal := fmt.Sprintf("%v", arg); isSensitiveString(strVal) {
357+
sanitizedArgs[i] = "[REDACTED]"
358+
} else {
359+
sanitizedArgs[i] = arg
360+
}
350361
}
351362
}
352363
}
353-
return args
364+
return sanitizedArgs
354365
}
355366

356367
func sanitizeStruct(rv reflect.Value) interface{} {
@@ -380,7 +391,8 @@ func sanitizeStruct(rv reflect.Value) interface{} {
380391
mapSanitized := make(map[interface{}]interface{})
381392
for _, key := range rv.Field(i).MapKeys() {
382393
val := rv.Field(i).MapIndex(key).Interface()
383-
if isSensitiveString(fmt.Sprintf("%v", key.Interface())) || isSensitive(val) {
394+
keyStr := fmt.Sprintf("%v", key.Interface())
395+
if isSensitiveString(keyStr) || isSensitive(val) {
384396
mapSanitized[key.Interface()] = "[REDACTED]"
385397
} else {
386398
mapSanitized[key.Interface()] = sanitizeArguments([]interface{}{val})[0]
@@ -396,9 +408,10 @@ func sanitizeStruct(rv reflect.Value) interface{} {
396408
}
397409

398410
func sanitizeMap(m map[string]interface{}) map[string]interface{} {
411+
result := make(map[string]interface{})
399412
for key, value := range m {
400413
if isSensitiveString(key) || isSensitive(value) {
401-
m[key] = "[REDACTED]"
414+
result[key] = "[REDACTED]"
402415
} else {
403416
rv := reflect.ValueOf(value)
404417
switch rv.Kind() {
@@ -407,31 +420,33 @@ func sanitizeMap(m map[string]interface{}) map[string]interface{} {
407420
subMap := make(map[interface{}]interface{})
408421
for _, subKey := range rv.MapKeys() {
409422
val := rv.MapIndex(subKey).Interface()
410-
if isSensitiveString(fmt.Sprintf("%v", subKey.Interface())) || isSensitive(val) {
423+
keyStr := fmt.Sprintf("%v", subKey.Interface())
424+
if isSensitiveString(keyStr) || isSensitive(val) {
411425
subMap[subKey.Interface()] = "[REDACTED]"
412426
} else {
413427
subMap[subKey.Interface()] = sanitizeArguments([]interface{}{val})[0]
414428
}
415429
}
416-
m[key] = subMap
430+
result[key] = subMap
417431
case reflect.Slice:
418432
slice := make([]interface{}, rv.Len())
419433
for j := 0; j < rv.Len(); j++ {
420434
slice[j] = sanitizeArguments([]interface{}{rv.Index(j).Interface()})[0]
421435
}
422-
m[key] = slice
436+
result[key] = slice
423437
case reflect.Struct:
424-
m[key] = sanitizeStruct(rv)
438+
result[key] = sanitizeStruct(rv)
425439
default:
426-
m[key] = value
440+
result[key] = value
427441
}
428442
}
429443
}
430-
return m
444+
return result
431445
}
432446

447+
// isSensitiveString checks if a string contains sensitive information
433448
func isSensitiveString(str string) bool {
434-
sensitiveKeywords := []string{"password", "secret", "token", "key"}
449+
sensitiveKeywords := []string{"password", "secret", "token", "key", "auth", "credential", "private"}
435450
str = strings.ToLower(str)
436451
for _, keyword := range sensitiveKeywords {
437452
if strings.Contains(str, keyword) {
@@ -441,13 +456,19 @@ func isSensitiveString(str string) bool {
441456
return false
442457
}
443458

459+
// isSensitive checks if a value contains sensitive information
444460
func isSensitive(arg interface{}) bool {
445-
// Add logic to identify sensitive data (e.g., passwords)
446-
// This may involve checking types or specific fields
447-
if str, ok := arg.(string); ok && strings.Contains(strings.ToLower(str), "password") {
448-
return true
461+
if arg == nil {
462+
return false
449463
}
450-
return false
464+
465+
// Check strings directly
466+
if str, ok := arg.(string); ok {
467+
return isSensitiveString(str)
468+
}
469+
470+
// Check string representation
471+
return isSensitiveString(fmt.Sprintf("%v", arg))
451472
}
452473

453474
// LogNode prints the node given if Verbose logging is enabled.

sql/system_settype.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,13 @@ func (t systemSetType) Convert(v interface{}) (interface{}, error) {
9090
case float64:
9191
// Float values aren't truly accepted, but the engine will give them when it should give ints.
9292
// Therefore, if the float doesn't have a fractional portion, we treat it as an int.
93-
if value >= float64(math.MinInt64) && value <= float64(math.MaxInt64) {
94-
if math.Trunc(value) == value { // Ensure no fractional part exists
95-
// Additional bounds check for out-of-range values
96-
if value < float64(math.MinInt64) || value > float64(math.MaxInt64) {
97-
return nil, ErrInvalidSystemVariableValue.New(t.varName, v) // Reject out-of-range values
98-
}
99-
intValue := int64(value)
100-
return t.SetType.Convert(intValue)
93+
if math.Trunc(value) == value { // Ensure no fractional part exists
94+
// Explicit bounds check for int64 range
95+
if value < float64(math.MinInt64) || value > float64(math.MaxInt64) {
96+
return nil, ErrInvalidSystemVariableValue.New(t.varName, v) // Reject out-of-range values
10197
}
98+
intValue := int64(value)
99+
return t.SetType.Convert(intValue)
102100
}
103101
return nil, ErrInvalidSystemVariableValue.New(t.varName, v) // Reject out-of-range values
104102
case decimal.Decimal:

sql/timetype.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ func (t timespanType) ConvertToTimespan(v interface{}) (Timespan, error) {
175175
case float32:
176176
return t.ConvertToTimespan(float64(value))
177177
case float64:
178+
if value < float64(math.MinInt64) || value > float64(math.MaxInt64) {
179+
return Timespan(0), fmt.Errorf("float64 value %f exceeds int64 bounds", value)
180+
}
178181
intValue := int64(value)
179182
microseconds := int64Abs(int64(math.Round((value - float64(intValue)) * float64(microsecondsPerSecond))))
180183
absValue := int64Abs(intValue)

0 commit comments

Comments
 (0)