trailofbits.go.invalid-usage-of-modified-variable.invalid-usage-of-modified-variable

Author
unknown
Download Count*
License
Variable $X
is likely modified and later used on error. In some cases this could result in panics due to a nil dereference
Run Locally
Run in CI
Defintion
rules:
- id: invalid-usage-of-modified-variable
message: "Variable `$X` is likely modified and later used on error. In some
cases this could result in panics due to a nil dereference "
languages:
- go
severity: WARNING
metadata:
category: security
cwe: "CWE-665: Improper Initialization"
subcategory:
- audit
confidence: HIGH
likelihood: MEDIUM
impact: MEDIUM
technology:
- --no-technology--
description: Possible unintentional assignment when an error occurs
references:
- https://blog.trailofbits.com/2019/11/07/attacking-go-vr-ttps/
license: CC-BY-NC-SA-4.0
patterns:
- pattern-either:
- pattern: |
$X, err = ...
if err != nil {
<... $X ...>
}
- pattern: |
$X, err := ...
if err != nil {
...
<... $X.$Y ...>
}
Examples
invalid-usage-of-modified-variable.go
package main
import (
"fmt"
)
type Engineer struct {
Id int
FName string
LName string
Age int
Address *Address
}
type Address struct {
City string
State string
}
type Log struct {
Id int
Message string
}
func main() {
engineers := getEngineers()
// ruleid: invalid-usage-of-modified-variable
eng1, err := getEngineerAtIndex(engineers, 5)
if err != nil {
fmt.Printf("Unable to obtain engineer with FName %s\n", eng1.FName)
}
// ruleid: invalid-usage-of-modified-variable
if eng2, err := getEngineerAtIndex(engineers, 6); err != nil {
fmt.Printf("Unable to obtain engineer with FName %s\n", eng2.FName)
}
eng3 := Engineer{4, "Lee", "Renaldo", 50, nil}
// ruleid: invalid-usage-of-modified-variable
eng3.Address, err = getEngineerAddressByIndex(engineers, 1)
if err != nil {
fmt.Printf("Unable to obtain address %#v!\n", eng3.Address)
}
// ruleid: invalid-usage-of-modified-variable
eng4, err := getEngineerAtIndex(engineers, 5)
if err != nil {
log := Log{
Id: eng4.Id,
Message: "Unable to obtain engineer",
}
fmt.Printf("%#v\n", log)
}
// ok: invalid-usage-of-modified-variable
if eng5, err := getEngineerAtIndex(engineers, 6); err == nil {
fmt.Printf("Obtained engineer with FName %s\n", eng5.FName)
}
fmt.Printf("Engineer 1: %s", fmt.Sprintf("%s %s", eng1.FName, eng1.LName))
}
func getEngineerAtIndex(slice []Engineer, idx int) (*Engineer, error) {
if idx >= len(slice) {
return nil, fmt.Errorf("invalid index")
}
return &slice[idx], nil
}
func getEngineerAddressByIndex(slice []Engineer, idx int) (*Address, error) {
if idx >= len(slice) {
return nil, fmt.Errorf("invalid index")
}
return slice[idx].Address, nil
}
func getEngineers() []Engineer {
return []Engineer{
{
1,
"James",
"Osterberg",
24,
&Address{
"Detroit",
"Michigan",
},
},
{
2,
"Althea",
"Gordon",
43,
&Address{
"New York",
"New York",
},
},
{
3,
"José-Manuel",
"Arthur Chao",
55,
&Address{
"Paris",
"Île-de-France",
},
},
}
}
Short Link: https://sg.run/WWQ2