Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(golang): add cwe 330 #284

Merged
merged 1 commit into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions rules/go/lang/insufficiently_random_values.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
patterns:
- pattern: |
$<MATH>.Seed()
filters:
- variable: MATH
detection: go_lang_insufficiently_random_values_init
scope: cursor
auxiliary:
- id: go_lang_insufficiently_random_values_init
patterns:
- import $<!>"math/rand"
- |
import (
$<!>"math/rand"
)
languages:
- go
metadata:
description: "Usage of insufficient random value"
remediation_message: |
## Description

Using predictable random values makes our application vulnerable to attacks,
especially if these values are used for security purposes.

## Remediations

✅ Use a stronger library when generating random values

```go
import (
"crypto/rand"
"encoding/base64"
"fmt"
)

func generateSecureToken(length int) (string, error) {
bytes := make([]byte, length)
_, err := rand.Read(bytes)
if err != nil {
return "", err
}

// Encode the binary data to a string for easier use
return base64.URLEncoding.EncodeToString(bytes), nil
}
```

## Resources

[Use of Insufficiently Random Values](https://cwe.mitre.org/data/definitions/330.html)

cwe_id:
- 330
id: go_lang_insufficiently_random_values
documentation_url: https://docs.bearer.com/reference/rules/go_lang_insufficiently_random_values
18 changes: 18 additions & 0 deletions tests/go/lang/insufficiently_random_values/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const {
createNewInvoker,
getEnvironment,
} = require("../../../helper.js")
const { ruleId, ruleFile, testBase } = getEnvironment(__dirname)

describe(ruleId, () => {
const invoke = createNewInvoker(ruleId, ruleFile, testBase)

test("insufficiently_random_values", () => {
const testCase = "main.go"

const results = invoke(testCase)

expect(results.Missing).toEqual([])
expect(results.Extra).toEqual([])
})
})
42 changes: 42 additions & 0 deletions tests/go/lang/insufficiently_random_values/testdata/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Use of bearer:expected go_lang_insufficiently_random_values to flag expected findings

package main

import (
"encoding/base64"
"fmt"
"math/rand"
"time"

crypto "crypto/rand"
)

func generateSecureToken(length int) (string, error) {
bytes := make([]byte, length)
_, err := crypto.Read(bytes)
if err != nil {
return "", err // Don't ignore errors!
}

// Encode the binary data to a string for easier use
return base64.URLEncoding.EncodeToString(bytes), nil
}

func generateToken() string {
// Seed the random number generator with the current time
// bearer:expected go_lang_insufficiently_random_values
rand.Seed(time.Now().UnixNano())

// Generate a token using a non-cryptographically secure random generator
token := ""
for i := 0; i < 10; i++ {
token += string(rand.Intn(26) + 'a')
}
return token
}

func main() {
// Generate and print a "random" token
fmt.Println("Generated Token:", generateToken())
fmt.Println("Generated Secure Token:", generateSecureToken())
}
Loading