Skip to content

Commit d0b66c2

Browse files
chore: removed ScoreParameters, Category and RuleType are now fields of Rule (#356)
<!-- Thanks for contributing to 2ms by offering a pull request. --> Closes # **Proposed Changes** <!-- Please describe the big picture of your changes here. If it fixes a bug or resolves a feature request, be sure to link to that issue. --> **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.
1 parent 4a66d1e commit d0b66c2

238 files changed

Lines changed: 1623 additions & 1422 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,8 @@ Other fields are optional and can be seen in the example bellow of a file with a
362362
severity: High # severity, can only be one of [Critical, High, Medium, Low, Info]
363363
tags: # identifiers for the rule, tags can be used as values of --rule and --ignore-rule flags
364364
- api-key
365-
scoreParameters: # scoreParameters can be omitted for overrides, in which case the respective default rule scoreParameters will be considered
366-
category: General # category of the rule, should be a string of type ruledefine.RuleCategory. Impacts cvss score
367-
ruleType: 4 # can go from 4 to 0, 4 being most severe. For overrides, if Category is defined, ruleType also needs to be defined, or otherwise it will be considered 0. Impacts cvss score
365+
category: General # category of the rule, should be a string of type ruledefine.RuleCategory. Can be omitted in custom rule, but if omitted and ruleId matches a default rule, the category will take the value of the category of that defaultRule. Impacts cvss score
366+
scoreRuleType: 4 # can go from 1 to 4, 4 being most severe. If omitted in rule it will take the value of 1. Impacts cvss score
368367
disableValidation: false # if true, disables validity check for this rule, regardless of --validate flag
369368
deprecated: false # if true, the rule will not be used in the scan, regardless of --rule flag
370369
allowLists: # allowed values to ignore if matched

cmd/config_test.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cmd
22

33
import (
4+
"fmt"
45
"os"
56
"path/filepath"
67
"testing"
@@ -297,11 +298,9 @@ func TestCustomRulesFlag(t *testing.T) {
297298
StopWords: []string{"example", "sample"},
298299
},
299300
},
300-
Tags: []string{"security", "credentials"},
301-
ScoreParameters: ruledefine.ScoreParameters{
302-
Category: "General",
303-
RuleType: 2,
304-
},
301+
Tags: []string{"security", "credentials"},
302+
Category: "General",
303+
ScoreRuleType: 2,
305304
DisableValidation: true,
306305
Deprecated: true,
307306
},
@@ -347,6 +346,12 @@ func TestCustomRulesFlag(t *testing.T) {
347346
expectedRules: nil,
348347
expectErrors: []error{errInvalidCustomRulesExtension},
349348
},
349+
{
350+
name: "Invalid rule type",
351+
customRulesFile: "testData/customRulesInvalidRuleType.json",
352+
expectedRules: nil,
353+
expectErrors: []error{fmt.Errorf("cannot unmarshal number -2 into Go struct field Rule.scoreRuleType of type uint8")},
354+
},
350355
}
351356

352357
for _, tt := range tests {

cmd/main_test.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,13 @@ func TestPreRun(t *testing.T) {
8383
engineConfigVar: engine.EngineConfig{
8484
CustomRules: []*ruledefine.Rule{
8585
{
86-
RuleID: "db18ccf1-4fbf-49f6-aec1-939a2e5464c0",
87-
RuleName: "mock-rule",
88-
Description: "Match passwords",
89-
Regex: "[A-Za-z0-9]{32})",
90-
Severity: "mockSeverity",
91-
ScoreParameters: ruledefine.ScoreParameters{
92-
Category: "mockCategory",
93-
RuleType: 10,
94-
},
86+
RuleID: "db18ccf1-4fbf-49f6-aec1-939a2e5464c0",
87+
RuleName: "mock-rule",
88+
Description: "Match passwords",
89+
Regex: "[A-Za-z0-9]{32})",
90+
Severity: "mockSeverity",
91+
Category: "mockCategory",
92+
ScoreRuleType: 10,
9593
},
9694
{
9795
RuleID: "b47a1995-6572-41bb-b01d-d215b43ab089",
@@ -108,7 +106,7 @@ func TestPreRun(t *testing.T) {
108106
" mockSeverity not one of ([Critical High Medium Low Info])"),
109107
fmt.Errorf("rule#0;RuleID-db18ccf1-4fbf-49f6-aec1-939a2e5464c0: invalid category:" +
110108
" mockCategory not an acceptable category of type RuleCategory"),
111-
fmt.Errorf("rule#0;RuleID-db18ccf1-4fbf-49f6-aec1-939a2e5464c0: invalid rule type: 10 not an acceptable uint8 value, maximum is 4"),
109+
fmt.Errorf("rule#0;RuleID-db18ccf1-4fbf-49f6-aec1-939a2e5464c0: invalid rule type: 10 not an acceptable uint8 value, should be between 1 and 4"),
112110
},
113111
},
114112
{
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[
2+
{
3+
"ruleId": "db18ccf1-4fbf-49f6-aec1-939a2e5464c0",
4+
"ruleName": "mock-rule",
5+
"description": "Match passwords",
6+
"regex": "[A-Za-z0-9]{32}",
7+
"keywords": ["password", "pwd"],
8+
"entropy": 3.5,
9+
"path": "secrets/passwords.txt",
10+
"secretGroup": 1,
11+
"severity": "High",
12+
"tags": ["security", "credentials"],
13+
"category": "General",
14+
"scoreRuleType": -2
15+
}
16+
]

cmd/testData/customRulesValid.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@
2121
}
2222
],
2323
"tags": ["security", "credentials"],
24-
"scoreParameters": {
25-
"category": "General",
26-
"ruleType": 2
27-
},
24+
"category": "General",
25+
"scoreRuleType": 2,
2826
"disableValidation": true,
2927
"deprecated": true
3028
},

cmd/testData/customRulesValid.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@
2525
tags:
2626
- security
2727
- credentials
28-
scoreParameters:
29-
category: General
30-
ruleType: 2
28+
category: General
29+
scoreRuleType: 2
3130
disableValidation: true
3231
deprecated: true
3332

engine/engine.go

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ func (e *Engine) addExtrasToSecret(secret *secrets.Secret) {
740740
// add general extra data
741741
extra.Mtxs.Lock(secret.ID)
742742
secret.RuleName = e.rules[secret.RuleID].RuleName
743-
secret.RuleCategory = string(e.rules[secret.RuleID].ScoreParameters.Category)
743+
secret.RuleCategory = string(e.rules[secret.RuleID].Category)
744744
extra.Mtxs.Unlock(secret.ID)
745745

746746
// add rule specific extra data
@@ -869,20 +869,17 @@ func CheckRulesRequiredFields(rulesToCheck []*ruledefine.Rule) error {
869869
}
870870
}
871871

872-
if rule.ScoreParameters.Category != "" {
873-
if _, ok := score.CategoryScoreMap[rule.ScoreParameters.Category]; !ok {
874-
invalidCategoryError := fmt.Errorf("%w: %s not an acceptable category of type RuleCategory",
875-
errInvalidCategory, rule.ScoreParameters.Category)
876-
err = errors.Join(err, buildCustomRuleError(i, rule, invalidCategoryError))
877-
}
872+
_, validCategory := score.CategoryScoreMap[rule.Category]
873+
if rule.Category != "" && !validCategory {
874+
invalidCategoryError := fmt.Errorf("%w: %s not an acceptable category of type RuleCategory",
875+
errInvalidCategory, rule.Category)
876+
err = errors.Join(err, buildCustomRuleError(i, rule, invalidCategoryError))
878877
}
879878

880-
if rule.ScoreParameters.RuleType != 0 {
881-
if rule.ScoreParameters.RuleType > score.RuleTypeMaxValue {
882-
invalidRuleTypeError := fmt.Errorf("%w: %d not an acceptable uint8 value, maximum is %d",
883-
errInvalidRuleType, rule.ScoreParameters.RuleType, score.RuleTypeMaxValue)
884-
err = errors.Join(err, buildCustomRuleError(i, rule, invalidRuleTypeError))
885-
}
879+
if rule.ScoreRuleType != 0 && rule.ScoreRuleType > score.RuleTypeMaxValue {
880+
invalidRuleTypeError := fmt.Errorf("%w: %d not an acceptable uint8 value, should be between 1 and 4",
881+
errInvalidRuleType, rule.ScoreRuleType)
882+
err = errors.Join(err, buildCustomRuleError(i, rule, invalidRuleTypeError))
886883
}
887884
}
888885

engine/engine_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ func TestProcessSecretsExtras(t *testing.T) {
10771077
ID: "mockId",
10781078
RuleID: ruledefine.JWT().RuleID,
10791079
RuleName: ruledefine.JWT().RuleName,
1080-
RuleCategory: string(ruledefine.JWT().ScoreParameters.Category),
1080+
RuleCategory: string(ruledefine.JWT().Category),
10811081
Value: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtb2NrU3ViMSIsIm5hbWUiOiJtb2NrTmFtZTEifQ.dummysignature1",
10821082
ExtraDetails: map[string]interface{}{
10831083
"secretDetails": map[string]interface{}{
@@ -1090,7 +1090,7 @@ func TestProcessSecretsExtras(t *testing.T) {
10901090
ID: "mockId2",
10911091
RuleID: ruledefine.JWT().RuleID,
10921092
RuleName: ruledefine.JWT().RuleName,
1093-
RuleCategory: string(ruledefine.JWT().ScoreParameters.Category),
1093+
RuleCategory: string(ruledefine.JWT().Category),
10941094
Value: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtb2NrU3ViMiIsIm5hbWUiOiJtb2NrTmFtZTIifQ.dummysignature2",
10951095
ExtraDetails: map[string]interface{}{
10961096
"secretDetails": map[string]interface{}{
@@ -1103,7 +1103,7 @@ func TestProcessSecretsExtras(t *testing.T) {
11031103
ID: "mockId3",
11041104
RuleID: ruledefine.HubSpot().RuleID,
11051105
RuleName: ruledefine.HubSpot().RuleName,
1106-
RuleCategory: string(ruledefine.HubSpot().ScoreParameters.Category),
1106+
RuleCategory: string(ruledefine.HubSpot().Category),
11071107
Value: "mockValue",
11081108
},
11091109
},
@@ -1184,7 +1184,8 @@ func TestProcessEvaluationWithValidation(t *testing.T) {
11841184
RuleName: ruledefine.GitHubPat().RuleName,
11851185
Regex: ruledefine.GitHubPat().Regex,
11861186
Severity: ruledefine.GitHubPat().Severity,
1187-
ScoreParameters: ruledefine.GitlabPat().ScoreParameters,
1187+
Category: ruledefine.GitHubPat().Category,
1188+
ScoreRuleType: ruledefine.GitHubPat().ScoreRuleType,
11881189
DisableValidation: true,
11891190
},
11901191
},

engine/rules/ruledefine/1password_secret_key.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ var onePasswordSecretKeyRegex = regexp.MustCompile(
1212
func OnePasswordSecretKey() *Rule {
1313
// define rule
1414
return &Rule{
15-
RuleID: "4068d686-6833-4976-8f4a-5397e75c7fc5",
16-
Description: "Uncovered a possible 1Password secret key, potentially compromising access to secrets in vaults.",
17-
RuleName: "1Password-Secret-Key",
18-
Regex: onePasswordSecretKeyRegex,
19-
Entropy: 3.8,
20-
Keywords: []string{"A3-"},
21-
Severity: "High",
22-
Tags: []string{TagPrivateKey},
23-
ScoreParameters: ScoreParameters{Category: CategoryAuthenticationAndAuthorization, RuleType: 4},
15+
RuleID: "4068d686-6833-4976-8f4a-5397e75c7fc5",
16+
Description: "Uncovered a possible 1Password secret key, potentially compromising access to secrets in vaults.",
17+
RuleName: "1Password-Secret-Key",
18+
Regex: onePasswordSecretKeyRegex,
19+
Entropy: 3.8,
20+
Keywords: []string{"A3-"},
21+
Severity: "High",
22+
Tags: []string{TagPrivateKey},
23+
Category: CategoryAuthenticationAndAuthorization,
24+
ScoreRuleType: 4,
2425
}
2526
}

engine/rules/ruledefine/1password_service_account.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ var onePasswordServiceAccountTokenRegex = regexp.MustCompile(`ops_eyJ[a-zA-Z0-9+
1010
func OnePasswordServiceAccountToken() *Rule {
1111
// define rule
1212
return &Rule{
13-
RuleID: "0ea85582-ea27-4f6f-b5f0-db3c4a75a07e",
14-
RuleName: "1Password-Service-Account-Token",
15-
Description: "Uncovered a possible 1Password service account token, potentially compromising access to secrets in vaults.",
16-
Regex: onePasswordServiceAccountTokenRegex,
17-
Entropy: 4,
18-
Keywords: []string{"ops_"},
19-
Severity: "High",
20-
Tags: []string{TagAccessToken},
21-
ScoreParameters: ScoreParameters{Category: CategoryAuthenticationAndAuthorization, RuleType: 4},
13+
RuleID: "0ea85582-ea27-4f6f-b5f0-db3c4a75a07e",
14+
RuleName: "1Password-Service-Account-Token",
15+
Description: "Uncovered a possible 1Password service account token, potentially compromising access to secrets in vaults.",
16+
Regex: onePasswordServiceAccountTokenRegex,
17+
Entropy: 4,
18+
Keywords: []string{"ops_"},
19+
Severity: "High",
20+
Tags: []string{TagAccessToken},
21+
Category: CategoryAuthenticationAndAuthorization,
22+
ScoreRuleType: 4,
2223
}
2324
}

0 commit comments

Comments
 (0)