-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: ast-68111 fix failing scan rule validation (#251)
<!-- Thanks for contributing to 2ms by offering a pull request. --> Closes # **Proposed Changes** <!-- There were issues with the validation of one rule, plaid-client-id. Sometimes, auto-generated secrets during validation are bellow the entropy threshold of the secret, causing the 2ms scan to fail. In order to fix this the rule is now defined in 2ms and loaded from this code, with the only difference being that the entropy value was changed from 3.5 to 3.0. vault-service-token was also added to 2ms because newer versions of gitleaks have the same problem for that rule. This is just a quick fix. The idea is move to a similar solution to gitleaks, with rules being loaded from a config file instead of loaded every scan. --> **Checklist** - [ ] I covered my changes with tests. - [ ] I Updated the documentation that is affected by my changes: - [ ] Change in the CLI arguments - [ ] Change in the configuration file I submit this contribution under the Apache-2.0 license.
- Loading branch information
1 parent
4b9e443
commit 3208f45
Showing
6 changed files
with
140 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package rules | ||
|
||
import ( | ||
"github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" | ||
"github.com/zricethezav/gitleaks/v8/config" | ||
) | ||
|
||
// Using this local version because gitleaks has entropy as 3.5, which causes issues on this rule's validation | ||
func PlaidAccessID() *config.Rule { | ||
// define rule | ||
r := config.Rule{ | ||
RuleID: "plaid-client-id", | ||
Description: "Uncovered a Plaid Client ID, which could lead to unauthorized financial service integrations and data breaches.", | ||
Regex: generateSemiGenericRegex([]string{"plaid"}, alphaNumeric("24"), true), | ||
|
||
Entropy: 3.0, | ||
Keywords: []string{ | ||
"plaid", | ||
}, | ||
} | ||
|
||
// validate | ||
tps := []string{ | ||
generateSampleSecret("plaid", secrets.NewSecret(alphaNumeric("24"))), | ||
} | ||
return validate(r, tps, nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package rules | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
"strings" | ||
) | ||
|
||
const ( | ||
// case insensitive prefix | ||
caseInsensitive = `(?i)` | ||
|
||
// identifier prefix (just an ignore group) | ||
identifierCaseInsensitivePrefix = `(?i:` | ||
identifierCaseInsensitiveSuffix = `)` | ||
identifierPrefix = `(?:` | ||
identifierSuffix = `)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}` | ||
|
||
// commonly used assignment operators or function call | ||
operator = `(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)` | ||
|
||
// boundaries for the secret | ||
// \x60 = ` | ||
secretPrefixUnique = `\b(` | ||
secretPrefix = `(?:'|\"|\s|=|\x60){0,5}(` | ||
secretSuffix = `)(?:['|\"|\n|\r|\s|\x60|;]|$)` | ||
) | ||
|
||
func generateSemiGenericRegex(identifiers []string, secretRegex string, isCaseInsensitive bool) *regexp.Regexp { | ||
var sb strings.Builder | ||
// The identifiers should always be case-insensitive. | ||
// This is inelegant but prevents an extraneous `(?i:)` from being added to the pattern; it could be removed. | ||
if isCaseInsensitive { | ||
sb.WriteString(caseInsensitive) | ||
writeIdentifiers(&sb, identifiers) | ||
} else { | ||
sb.WriteString(identifierCaseInsensitivePrefix) | ||
writeIdentifiers(&sb, identifiers) | ||
sb.WriteString(identifierCaseInsensitiveSuffix) | ||
} | ||
sb.WriteString(operator) | ||
sb.WriteString(secretPrefix) | ||
sb.WriteString(secretRegex) | ||
sb.WriteString(secretSuffix) | ||
return regexp.MustCompile(sb.String()) | ||
} | ||
|
||
func writeIdentifiers(sb *strings.Builder, identifiers []string) { | ||
sb.WriteString(identifierPrefix) | ||
sb.WriteString(strings.Join(identifiers, "|")) | ||
sb.WriteString(identifierSuffix) | ||
} | ||
|
||
func generateUniqueTokenRegex(secretRegex string, isCaseInsensitive bool) *regexp.Regexp { | ||
var sb strings.Builder | ||
if isCaseInsensitive { | ||
sb.WriteString(caseInsensitive) | ||
} | ||
sb.WriteString(secretPrefixUnique) | ||
sb.WriteString(secretRegex) | ||
sb.WriteString(secretSuffix) | ||
return regexp.MustCompile(sb.String()) | ||
} | ||
|
||
func generateSampleSecret(identifier string, secret string) string { | ||
return fmt.Sprintf("%s_api_token = \"%s\"", identifier, secret) | ||
} | ||
|
||
func alphaNumeric(size string) string { | ||
return fmt.Sprintf(`[a-z0-9]{%s}`, size) | ||
} | ||
|
||
func alphaNumericExtendedShort(size string) string { | ||
return fmt.Sprintf(`[a-z0-9_-]{%s}`, size) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package rules | ||
|
||
import ( | ||
"github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" | ||
"github.com/zricethezav/gitleaks/v8/config" | ||
) | ||
|
||
// Using this local version because newer versions of gitleaks have an entropy value, which was set as too high | ||
// It's here as prevention in case a newer version of gitleaks starts getting used and causes issues on this rule | ||
// If gitleaks is updated on 2ms and the new version of this rule has entropy, set it to 3.0 | ||
func VaultServiceToken() *config.Rule { | ||
// define rule | ||
r := config.Rule{ | ||
Description: "Identified a Vault Service Token, potentially compromising infrastructure security and access to sensitive credentials.", | ||
RuleID: "vault-service-token", | ||
Regex: generateUniqueTokenRegex(`hvs\.[a-z0-9_-]{90,100}`, true), | ||
Keywords: []string{"hvs"}, | ||
} | ||
|
||
// validate | ||
tps := []string{ | ||
generateSampleSecret("vault", "hvs."+secrets.NewSecret(alphaNumericExtendedShort("90"))), | ||
} | ||
return validate(r, tps, nil) | ||
} |