Incorrect access of indexable resource ('Range Error')
Description
Go's `for... range` statements create an iteration variable for each iteration of the loop. By taking the address of this iteration variable, the value of the address will be re-used and always point to the same location in memory. This can have unexpected behavior if the address is stored or re-used.
Examples
Insecure Code
go
for _, n := range []someStruct{{1}, {2}, {3}, {4}} { fmt.Printf("%p\n", &n) }Secure Code
go
for _, n := range []someStruct{{1}, {2}, {3}, {4}} { fmt.Printf("%d\n", n.x) },for _, n := range []someStruct{{1}, {2}, {3}, {4}} { p := n; fmt.Printf("%p\n", &p) },structData := []someStruct{{1}, {2}, {3}, {4}}; for idx := range structData { fmt.Printf("%p\n", &structData[idx]) }Remediation
To fix this issue, do not reference the address of the variable, re-assign the iteration variable to a new variable, or use the address of the indexed variable.
Rule Details
| Field | Value |
|---|---|
| ID | CODE-0793 |
| Category | Generic |
| Severity | MEDIUM |
| CWE | CWE-118 |
| Confidence | HIGH |
| Impact | MEDIUM |
| Likelihood | MEDIUM |
| Exploitability | MODERATE |
| Tags | go, range, iteration variable |
| OWASP | A6:2017-Security Misconfiguration, A05:2021-Security Misconfiguration |