Skip to content

Commit

Permalink
fix(golang): permissive regex rule for validation purposes
Browse files Browse the repository at this point in the history
  • Loading branch information
elsapet committed Jul 4, 2024
1 parent 9d5359a commit f3cd3c5
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 16 deletions.
33 changes: 21 additions & 12 deletions rules/go/lang/permissive_regex_validation.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
patterns:
- pattern: |
$<REGEXP>.$<METHOD>($<PATTERN>$<...>)
- pattern: $<PERMISSIVE_REGEXP>.$<METHOD>($<...>)
filters:
- variable: REGEXP
detection: go_lang_permissive_regex_validation_regexp
- variable: PERMISSIVE_REGEXP
detection: go_lang_permissive_regex_validation_permissive_regexp
- variable: METHOD
values:
- Compile
- MustCompile
- not:
variable: PATTERN
string_regex: \A.\\A.*\\[zZ].\z
- Match
- MatchString
auxiliary:
- id: go_lang_permissive_regex_validation_permissive_regexp
patterns:
- pattern: $<REGEXP>.$<METHOD>($<PATTERN>$<...>)
filters:
- variable: REGEXP
detection: go_lang_permissive_regex_validation_regexp
- variable: METHOD
values:
- Compile
- MustCompile
- not:
variable: PATTERN
string_regex: \A.\\A.*\\[zZ].\z
- id: go_lang_permissive_regex_validation_regexp
patterns:
- import $<!>"regexp"
Expand All @@ -22,15 +31,15 @@ auxiliary:
languages:
- go
metadata:
description: "Missing validation for regular expression"
description: Permissive regular expression used in matching
remediation_message: |-
## Description
When using regular expressions for validation, it's crucial to specify the start and end of the text boundaries. This ensures the entire text is validated, not just parts of it. Use \A and \z (or \Z) over ^ and $ to specify text boundaries, because these accurately mark the beginning and end of the text, even in multiline mode.
When matching with regular expressions -- especially for validation purposes -- it is crucial to specify the start and end of the text boundaries. This ensures the entire text is validated, not just parts of it, and prevents attackers from bypassing validation with partially matching input. Use \A and \z (or \Z) over ^ and $ to specify text boundaries, because these accurately mark the beginning and end of the text, even in multiline mode.
## Remediations
- **Do not** use regular expressions without specifying start and end boundaries. This can lead to incomplete validation.
- **Do not** use regular expressions for validation without specifying start and end boundaries. This can lead to partial matches being considered valid, when they may contain unsafe input.
```go
regexp.MustCompile("foo") // unsafe
```
Expand Down
20 changes: 16 additions & 4 deletions tests/go/lang/permissive_regex_validation/testdata/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,23 @@ import (
"regexp"
)

func bad() {
func permissiveRegex(input string) {
re := regexp.MustCompile("[a-zA-Z0-9]*")

// likely not validation - we ignore this
re.ReplaceAllString(input, "foo")

// bearer:expected go_lang_permissive_regex_validation
re.Match([]byte(input))
// bearer:expected go_lang_permissive_regex_validation
_ = regexp.MustCompile("[a-zA-Z0-9]*")
re.MatchString(input)
}

func good() {
_ = regexp.MustCompile(`\A[a-zA-Z0-9]*\z`)
func goodRegexp(input string) {
re := regexp.MustCompile(`\A[a-zA-Z0-9]*\z`)
if re.MatchString(input) {
// continue with valid string
} else {
// handle invalid string
}
}

0 comments on commit f3cd3c5

Please sign in to comment.