go.lang.security.audit.unsafe-reflect-by-name.unsafe-reflect-by-name

Author
7,585
Download Count*
License
If an attacker can supply values that the application then uses to determine which method or field to invoke, the potential exists for the attacker to create control flow paths through the application that were not intended by the application developers. This attack vector may allow the attacker to bypass authentication or access control checks or otherwise cause the application to behave in an unexpected manner.
Run Locally
Run in CI
Defintion
rules:
- id: unsafe-reflect-by-name
patterns:
- pattern-either:
- pattern: |
$SMTH.MethodByName($NAME,...)
- pattern: |
$SMTH.FieldByName($NAME,...)
- pattern-not: |
$SMTH.MethodByName("...",...)
- pattern-not: |
$SMTH.FieldByName("...",...)
- pattern-inside: |
import "reflect"
...
message: If an attacker can supply values that the application then uses to
determine which method or field to invoke, the potential exists for the
attacker to create control flow paths through the application that were
not intended by the application developers. This attack vector may allow
the attacker to bypass authentication or access control checks or
otherwise cause the application to behave in an unexpected manner.
metadata:
cwe:
- "CWE-470: Use of Externally-Controlled Input to Select Classes or Code
('Unsafe Reflection')"
owasp:
- A03:2021 - Injection
category: security
technology:
- go
confidence: LOW
references:
- https://owasp.org/Top10/A03_2021-Injection
subcategory:
- audit
likelihood: LOW
impact: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
severity: WARNING
languages:
- go
Examples
unsafe-reflect-by-name.go
package testing
import (
"bytes"
"fmt"
"reflect"
)
func (mf mapFmt) Format(s fmt.State, c rune, userInput string) {
refVal := mf.m
key := keys[i]
val := refVal.MapIndex(key)
// ruleid: unsafe-reflect-by-name
meth := key.MethodByName(userInput)
meth.Call(nil)[0]
return
}
func Test1(job interface{}, userInput string) {
jobData := make(map[string]interface{})
valueJ := reflect.ValueOf(job).Elem()
// ruleid: unsafe-reflect-by-name
jobData["color"] = valueJ.FieldByName(userInput).String()
return jobData
}
func OkTest(job interface{}, userInput string) {
jobData := make(map[string]interface{})
valueJ := reflect.ValueOf(job).Elem()
// ok: unsafe-reflect-by-name
meth := valueJ.MethodByName("Name")
// ok: unsafe-reflect-by-name
jobData["color"] = valueJ.FieldByName("color").String()
return jobData
}
Short Link: https://sg.run/R8Xv