Skip to content

Commit

Permalink
chore: clean up (#475)
Browse files Browse the repository at this point in the history
* chore: clean up

* chore: move devise inside rails instead of 3rd party

* refactor: move logic inside loadRules
  • Loading branch information
cfabianski authored Jan 31, 2023
1 parent 52483c8 commit 5c0b2b8
Show file tree
Hide file tree
Showing 19 changed files with 109 additions and 486 deletions.
40 changes: 8 additions & 32 deletions new/detector/composition/ruby/.snapshots/TestRuby-object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@
"Name": "user",
"Classification": {
"name": "user",
"data_type": {
"name": "Unique Identifier",
"uuid": "12d44ae0-1df7-4faf-9fb1-b46cc4b4dce9",
"category_uuid": "14124881-6b92-4fc5-8005-ea7c1c09592e"
},
"decision": {
"state": "valid",
"reason": "valid_object_with_valid_properties"
Expand All @@ -33,35 +28,16 @@
}
},
"Classification": {
"name": "user",
"name": "name",
"subject_name": "User",
"data_type": {
"name": "Fullname",
"uuid": "1617291b-bc22-4267-ad5e-8054b2505958",
"category_uuid": "14124881-6b92-4fc5-8005-ea7c1c09592e"
},
"decision": {
"state": "valid",
"reason": "valid_object_with_valid_properties"
}
},
"Properties": [
{
"Name": "name",
"Detection": {
"MatchNode": {},
"ContextNode": null,
"Data": {
"Name": "name"
}
},
"Classification": {
"name": "name",
"subject_name": "User",
"data_type": {
"name": "Fullname",
"uuid": "1617291b-bc22-4267-ad5e-8054b2505958",
"category_uuid": "14124881-6b92-4fc5-8005-ea7c1c09592e"
},
"decision": {
"state": "valid",
"reason": "known_pattern"
}
}
"reason": "known_pattern"
}
}
}
Expand Down
25 changes: 18 additions & 7 deletions pkg/commands/process/settings/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,32 @@ import (
"gopkg.in/yaml.v3"
)

func loadRules(externalRuleDirs []string, options flag.RuleOptions) (map[string]*Rule, error) {
func loadRules(externalRuleDirs []string, options flag.RuleOptions) (map[string]*Rule, map[string]*Rule, error) {
definitions := make(map[string]RuleDefinition)
builtInDefinitions := make(map[string]RuleDefinition)

if err := loadRuleDefinitions(definitions, rulesFs); err != nil {
return nil, fmt.Errorf("error loading default rules: %w", err)
return nil, nil, fmt.Errorf("error loading default rules: %s", err)
}

if err := loadRuleDefinitions(builtInDefinitions, builtInRulesFs); err != nil {
return nil, nil, fmt.Errorf("error loading default built-in rules: %s", err)
}

for _, dir := range externalRuleDirs {
if err := loadRuleDefinitions(definitions, os.DirFS(dir)); err != nil {
return nil, fmt.Errorf("error loading external rules from %s: %w", dir, err)
return nil, nil, fmt.Errorf("error loading external rules from %s: %w", dir, err)
}
}

if err := validateRuleOptionIDs(options, definitions); err != nil {
return nil, err
return nil, nil, err
}

enabledRules := getEnabledRules(options, definitions)
enabledRules := getEnabledRules(options, definitions, nil)
builtInRules := getEnabledRules(options, builtInDefinitions, enabledRules)

return buildRules(definitions, enabledRules), nil
return buildRules(builtInDefinitions, builtInRules), buildRules(definitions, enabledRules), nil
}

func loadRuleDefinitions(definitions map[string]RuleDefinition, dir fs.FS) error {
Expand Down Expand Up @@ -95,7 +101,7 @@ func validateRuleOptionIDs(options flag.RuleOptions, definitions map[string]Rule
return nil
}

func getEnabledRules(options flag.RuleOptions, definitions map[string]RuleDefinition) map[string]struct{} {
func getEnabledRules(options flag.RuleOptions, definitions map[string]RuleDefinition, rules map[string]struct{}) map[string]struct{} {
enabledRules := make(map[string]struct{})

for _, definition := range definitions {
Expand All @@ -105,6 +111,10 @@ func getEnabledRules(options flag.RuleOptions, definitions map[string]RuleDefini
continue
}

for ruleId := range rules {
enabledRules[ruleId] = struct{}{}
}

if len(options.OnlyRule) > 0 && !options.OnlyRule[id] {
continue
}
Expand All @@ -118,6 +128,7 @@ func getEnabledRules(options flag.RuleOptions, definitions map[string]RuleDefini
for _, dependencyID := range definition.Detectors {
enabledRules[dependencyID] = struct{}{}
}

}

return enabledRules
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ languages:
- ruby
detectors:
- schema_rb # built-in
- sql_lang_create_table
- sql_lang_create_table # built-in
processors:
- db_encrypted
- rails_encrypted
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
type: "risk"
languages:
- ruby
patterns:
- pattern: |
class $<_>
$<!>devise password_length: $<MIN_LENGTH>..$<MAX_LENGTH>
end
filters:
- either:
- variable: MAX_LENGTH
less_than: 35
- variable: MIN_LENGTH
less_than: 8
- pattern: |
Devise.setup do |$<CONFIG:identifier>|
$<CONFIG>.password_length = $<MIN_LENGTH>..$<MAX_LENGTH>
end
filters:
- variable: MIN_LENGTH
less_than: 8
- pattern: |
Devise.setup do |$<CONFIG:identifier>|
$<CONFIG>.password_length = $<LENGTH>
end
filters:
- variable: LENGTH
less_than: 8
match_violation: true
detect_presence: true
trigger: "global"
severity:
default: "high"
metadata:
description: "Enforce stronger password requirements."
remediation_message: |
## Description
Minimum password length should be enforced any time password creation occurs. This rule checks if configurations and validations made for passwords include a minimum length of 8.
## Remediations
✅ OWASP recommends a password length of at least 8 characters, which is easy to enforce at the model level in Rails using validation constraint:
```ruby
validates :password, presence: true, length: { minimum: 8, maximum: 255 }
```
<!--
## Resources
Coming soon.
-->
dsr_id: "DSR-8"
id: "ruby_rails_devise_password_length"
29 changes: 17 additions & 12 deletions pkg/commands/process/settings/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ import (
)

type Config struct {
Worker flag.WorkerOptions `mapstructure:"worker" json:"worker" yaml:"worker"`
Scan flag.ScanOptions `mapstructure:"scan" json:"scan" yaml:"scan"`
Report flag.ReportOptions `mapstructure:"report" json:"report" yaml:"report"`
Policies map[string]*Policy `mapstructure:"policies" json:"policies" yaml:"policies"`
Target string `mapstructure:"target" json:"target" yaml:"target"`
Rules map[string]*Rule `mapstructure:"rules" json:"rules" yaml:"rules"`
Worker flag.WorkerOptions `mapstructure:"worker" json:"worker" yaml:"worker"`
Scan flag.ScanOptions `mapstructure:"scan" json:"scan" yaml:"scan"`
Report flag.ReportOptions `mapstructure:"report" json:"report" yaml:"report"`
Policies map[string]*Policy `mapstructure:"policies" json:"policies" yaml:"policies"`
Target string `mapstructure:"target" json:"target" yaml:"target"`
Rules map[string]*Rule `mapstructure:"rules" json:"rules" yaml:"rules"`
BuiltInRules map[string]*Rule `mapstructure:"built_in_rules" json:"built_in_rules" yaml:"built_in_rules"`
}

type PolicyLevel string
Expand Down Expand Up @@ -148,6 +149,9 @@ var defaultPolicies []byte
//go:embed rules/*
var rulesFs embed.FS

//go:embed built_in_rules/*
var builtInRulesFs embed.FS

//go:embed policies/*
var policiesFs embed.FS

Expand All @@ -165,7 +169,7 @@ func (rule *Rule) PolicyType() bool {
func FromOptions(opts flag.Options) (Config, error) {
policies := DefaultPolicies()

rules, err := loadRules(opts.ExternalRuleDir, opts.RuleOptions)
builtInRules, rules, err := loadRules(opts.ExternalRuleDir, opts.RuleOptions)
if err != nil {
return Config{}, err
}
Expand All @@ -185,11 +189,12 @@ func FromOptions(opts flag.Options) (Config, error) {
}

config := Config{
Worker: opts.WorkerOptions,
Scan: opts.ScanOptions,
Report: opts.ReportOptions,
Policies: policies,
Rules: rules,
Worker: opts.WorkerOptions,
Scan: opts.ScanOptions,
Report: opts.ReportOptions,
Policies: policies,
Rules: rules,
BuiltInRules: builtInRules,
}

return config, nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/commands/process/worker/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func Start(port string) error {
response.ClassifierError = err.Error()
}

err = detectors.SetupCustomDetector(config.Rules)
err = detectors.SetupLegacyDetector(config.BuiltInRules)
if err != nil {
response.CustomDetectorError = err.Error()
}
Expand Down
36 changes: 0 additions & 36 deletions pkg/detectors/custom/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"io"
"os"
"regexp"
"sort"
"strings"

"github.com/bearer/curio/pkg/commands/process/settings"
Expand Down Expand Up @@ -66,10 +65,6 @@ func (detector *Detector) CompileRules(rulesConfig map[string]*settings.Rule) er

for ruleName, rule := range rulesConfig {
for _, lang := range rule.Languages {
if lang != "sql" {
continue
}

for _, rulePattern := range rule.Patterns {
compiledRule, err := detector.compileRule(rulePattern, lang, detector.paramIdGenerator)
if err != nil {
Expand All @@ -80,7 +75,6 @@ func (detector *Detector) CompileRules(rulesConfig map[string]*settings.Rule) er
compiledRule.Language = lang

compiledRule.RuleName = ruleName
compiledRule.Metavars = rule.Metavars
compiledRule.ParamParenting = rule.ParamParenting
compiledRule.DetectPresence = rule.DetectPresence
compiledRule.Pattern = rulePattern.Pattern
Expand All @@ -91,12 +85,6 @@ func (detector *Detector) CompileRules(rulesConfig map[string]*settings.Rule) er
}
}

for _, rules := range detector.rulesGroupedByLang {
sort.Slice(rules, func(i, j int) bool {
return strings.Compare(rules[i].RuleName, rules[j].RuleName) == -1
})
}

return nil
}

Expand Down Expand Up @@ -145,30 +133,6 @@ func (detector *Detector) ProcessFile(file *file.FileInfo, dir *file.Path, repor
}

return true, nil
case "ruby":
sitterLang := getLanguage(lang)
tree, err := parser.ParseFile(file, file.Path, sitterLang)
if err != nil {
return false, err
}

langDetector, err := detector.forLanguage(lang)
if err != nil {
return false, err
}

if err := langDetector.Annotate(tree); err != nil {
return false, err
}

for _, rule := range rules {
err := detector.executeRule(rule, tree, report, detector.idGenerator)
if err != nil {
return false, err
}
}

tree.Close()
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/detectors/detectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ type activeDetector struct {

var customDetector = InitializedDetector{reportdetectors.DetectorCustom, custom.New(&nodeid.UUIDGenerator{})}

func SetupCustomDetector(config map[string]*settings.Rule) error {
func SetupLegacyDetector(config map[string]*settings.Rule) error {
detector := customDetector.Detector.(*custom.Detector)

return detector.CompileRules(config)
Expand Down
14 changes: 0 additions & 14 deletions pkg/detectors/internal/testhelper/testhelper.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/bearer/curio/pkg/parser"
"github.com/bearer/curio/pkg/parser/nodeid"

createview "github.com/bearer/curio/pkg/report/create_view"
"github.com/bearer/curio/pkg/report/dependencies"
"github.com/bearer/curio/pkg/report/detections"
reportdetectors "github.com/bearer/curio/pkg/report/detectors"
Expand Down Expand Up @@ -143,19 +142,6 @@ func (report *InMemoryReport) AddDataType(
datatype.ExportClassified(report, detectionType, detectorType, idGenerator, values, nil)
}

func (report *InMemoryReport) AddCreateView(
detectorType reportdetectors.Type,
createview createview.View,
) {

report.CreateView = append(report.CreateView, &detections.Detection{
DetectorType: detectorType,
Value: createview,
Source: createview.Source,
Type: detections.TypeCreateView,
})
}

func (report *InMemoryReport) AddInterface(
detectorType reportdetectors.Type,
data interfaces.Interface,
Expand Down
Loading

0 comments on commit 5c0b2b8

Please sign in to comment.