Skip to content

Commit 08e59de

Browse files
committed
working on integrating script engine into threagile
1 parent cfaacff commit 08e59de

File tree

56 files changed

+10901
-8239
lines changed

Some content is hidden

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

56 files changed

+10901
-8239
lines changed

cmd/risk_demo/main.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,12 @@ func main() {
4949
os.Exit(-2)
5050
}
5151

52-
generatedRisks := new(customRiskRule).GenerateRisks(&input)
52+
generatedRisks, riskError := new(customRiskRule).GenerateRisks(&input)
53+
if riskError != nil {
54+
_, _ = fmt.Fprintf(os.Stderr, "failed to generate risks: %v\n", riskError)
55+
os.Exit(-2)
56+
}
57+
5358
outData, marshalError := json.Marshal(generatedRisks)
5459
if marshalError != nil {
5560
_, _ = fmt.Fprintf(os.Stderr, "failed to print generated risks: %v\n", marshalError)
@@ -89,17 +94,17 @@ func (r customRiskRule) SupportedTags() []string {
8994
return []string{"demo tag"}
9095
}
9196

92-
func (r customRiskRule) GenerateRisks(parsedModel *types.Model) []types.Risk {
93-
generatedRisks := make([]types.Risk, 0)
97+
func (r customRiskRule) GenerateRisks(parsedModel *types.Model) ([]*types.Risk, error) {
98+
generatedRisks := make([]*types.Risk, 0)
9499
for _, techAsset := range parsedModel.TechnicalAssets {
95100
generatedRisks = append(generatedRisks, createRisk(techAsset))
96101
}
97-
return generatedRisks
102+
return generatedRisks, nil
98103
}
99104

100-
func createRisk(technicalAsset *types.TechnicalAsset) types.Risk {
105+
func createRisk(technicalAsset *types.TechnicalAsset) *types.Risk {
101106
category := new(customRiskRule).Category()
102-
risk := types.Risk{
107+
risk := &types.Risk{
103108
CategoryId: category.ID,
104109
Severity: types.CalculateSeverity(types.VeryLikely, types.MediumImpact),
105110
ExploitationLikelihood: types.VeryLikely,

cmd/script/main.go

Lines changed: 19 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,99 +2,52 @@ package main
22

33
import (
44
"fmt"
5-
"github.com/threagile/threagile/pkg/common"
6-
"github.com/threagile/threagile/pkg/input"
7-
"github.com/threagile/threagile/pkg/model"
85
"github.com/threagile/threagile/pkg/script"
9-
"github.com/threagile/threagile/pkg/security/risks"
6+
"github.com/threagile/threagile/pkg/security/types"
107
"gopkg.in/yaml.v3"
118
"os"
129
"path/filepath"
1310
)
1411

1512
func main() {
16-
ruleData, ruleReadError := os.ReadFile(filepath.Join("test", "risk-category.yaml"))
13+
scriptFilename := filepath.Join("test", "risk-category.yaml")
14+
ruleData, ruleReadError := os.ReadFile(scriptFilename)
1715
if ruleReadError != nil {
1816
fmt.Printf("error reading risk category: %v\n", ruleReadError)
1917
return
2018
}
2119

22-
scripts, parseError := new(script.Script).ParseScripts(ruleData)
20+
newRule, parseError := new(script.RiskRule).ParseFromData(ruleData)
2321
if parseError != nil {
24-
fmt.Printf("error parsing scripts: %v\n", parseError)
22+
fmt.Printf("error parsing scripts from %q: %v\n", scriptFilename, parseError)
2523
return
2624
}
2725

28-
modelData, modelReadError := os.ReadFile(filepath.Join("test", "parsed-model.yaml"))
26+
modelFilename := filepath.Join("test", "parsed-model.yaml")
27+
modelData, modelReadError := os.ReadFile(modelFilename)
2928
if modelReadError != nil {
3029
fmt.Printf("error reading model: %v\n", modelReadError)
3130
return
3231
}
3332

34-
inputModel := new(input.Model)
35-
modelUnmarshalError := yaml.Unmarshal(modelData, inputModel)
33+
parsedModel := new(types.Model)
34+
modelUnmarshalError := yaml.Unmarshal(modelData, parsedModel)
3635
if modelUnmarshalError != nil {
37-
fmt.Printf("error parsing model: %v\n", modelUnmarshalError)
36+
fmt.Printf("error parsing model from %q: %v\n", modelFilename, modelUnmarshalError)
3837
return
3938
}
4039

41-
/*
42-
categoriesModel := new(input.Model)
43-
riskUnmarshalError := yaml.Unmarshal(riskData, categoriesModel)
44-
if riskUnmarshalError != nil {
45-
fmt.Printf("error parsing risk category: %v\n", riskUnmarshalError)
46-
return
47-
}
48-
*/
49-
50-
parsedModel, modelError := model.ParseModel(&common.Config{}, inputModel, make(risks.RiskRules), make(risks.RiskRules))
51-
if modelError != nil {
52-
fmt.Printf("error importing model: %v\n", modelError)
40+
risks, riskError := newRule.GenerateRisks(parsedModel)
41+
if riskError != nil {
42+
fmt.Printf("error generating risks for %q: %v\n", newRule.Category().ID, riskError)
5343
return
5444
}
5545

56-
_ = parsedModel
57-
_ = scripts
58-
/*
59-
var risk types.RiskCategory
60-
if categoriesModel.CustomRiskCategories != nil {
61-
for _, item := range categoriesModel.CustomRiskCategories {
62-
risk = item
63-
}
64-
}
65-
66-
if len(categoriesModel.CustomRiskCategories) == 0 {
67-
fmt.Printf("no risk categories\n")
68-
return
69-
}
70-
71-
for name, script := range scripts {
72-
scope := new(script.Scope)
73-
addError := scope.Init(parsedModel, &risk, script.Utils())
74-
if addError != nil {
75-
fmt.Printf("error adding model to scope for %q: %v\n", name, addError)
76-
return
77-
}
78-
79-
risks, errorLiteral, riskError := script.GenerateRisks(scope)
80-
if riskError != nil {
81-
fmt.Printf("error generating risks for %q: %v\n", name, riskError)
82-
83-
if len(errorLiteral) > 0 {
84-
fmt.Printf("in:\n%v\n", script.IndentPrintf(1, errorLiteral))
85-
}
86-
87-
return
88-
}
89-
90-
printedRisks, printError := yaml.Marshal(risks)
91-
if printError != nil {
92-
fmt.Printf("error printing risks for %q: %v\n", name, printError)
93-
return
94-
}
95-
96-
fmt.Printf("generated risks for %q: \n%v\n", name, string(printedRisks))
97-
}
46+
printedRisks, printError := yaml.Marshal(risks)
47+
if printError != nil {
48+
fmt.Printf("error printing risks for %q: %v\n", newRule.Category().ID, printError)
49+
return
50+
}
9851

99-
*/
52+
fmt.Printf("generated risks for %q: \n%v\n", newRule.Category().ID, string(printedRisks))
10053
}

pkg/common/config.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package common
22

33
import (
44
"encoding/json"
5+
"errors"
56
"fmt"
67
"os"
78
"path/filepath"
@@ -157,39 +158,49 @@ func (c *Config) Load(configFilename string) error {
157158

158159
c.Merge(config, values)
159160

161+
errorList := make([]error, 0)
160162
c.TempFolder = c.CleanPath(c.TempFolder)
161163
tempDirError := os.MkdirAll(c.TempFolder, 0700)
162164
if tempDirError != nil {
163-
return fmt.Errorf("failed to create temp dir %q: %v", c.TempFolder, tempDirError)
165+
errorList = append(errorList, fmt.Errorf("failed to create temp dir %q: %v", c.TempFolder, tempDirError))
164166
}
165167

166168
c.OutputFolder = c.CleanPath(c.OutputFolder)
167169
outDirError := os.MkdirAll(c.OutputFolder, 0700)
168170
if outDirError != nil {
169-
return fmt.Errorf("failed to create output dir %q: %v", c.OutputFolder, outDirError)
171+
errorList = append(errorList, fmt.Errorf("failed to create output dir %q: %v", c.OutputFolder, outDirError))
170172
}
171173

172174
c.AppFolder = c.CleanPath(c.AppFolder)
173175
appDirError := c.checkDir(c.AppFolder, "app")
174176
if appDirError != nil {
175-
return appDirError
177+
errorList = append(errorList, appDirError)
176178
}
177179

178180
c.PluginFolder = c.CleanPath(c.PluginFolder)
179181
binDirError := c.checkDir(c.PluginFolder, "plugin")
180182
if binDirError != nil {
181-
return binDirError
183+
errorList = append(errorList, binDirError)
182184
}
183185

184186
c.DataFolder = c.CleanPath(c.DataFolder)
185187
dataDirError := c.checkDir(c.DataFolder, "data")
186188
if dataDirError != nil {
187-
return dataDirError
189+
errorList = append(errorList, dataDirError)
188190
}
189191

190192
c.TechnologyFilename = c.CleanPath(c.TechnologyFilename)
191193

192-
return c.CheckServerFolder()
194+
serverFolderError := c.CheckServerFolder()
195+
if serverFolderError != nil {
196+
errorList = append(errorList, serverFolderError)
197+
}
198+
199+
if len(errorList) > 0 {
200+
return errors.Join(errorList...)
201+
}
202+
203+
return nil
193204
}
194205

195206
func (c *Config) CheckServerFolder() error {

pkg/model/custom-risk-category.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package model
33
import (
44
"fmt"
55
"github.com/threagile/threagile/pkg/security/risks"
6-
"log"
76
"strings"
87

98
"github.com/threagile/threagile/pkg/security/types"
@@ -33,18 +32,18 @@ func (what *CustomRiskCategory) SupportedTags() []string {
3332
return what.Tags
3433
}
3534

36-
func (what *CustomRiskCategory) GenerateRisks(parsedModel *types.Model) []*types.Risk {
35+
func (what *CustomRiskCategory) GenerateRisks(parsedModel *types.Model) ([]*types.Risk, error) {
3736
if what.runner == nil {
38-
return nil
37+
return nil, nil
3938
}
4039

4140
generatedRisks := make([]*types.Risk, 0)
4241
runError := what.runner.Run(parsedModel, &generatedRisks, "-generate-risks")
4342
if runError != nil {
44-
log.Fatalf("Failed to generate risks for custom risk rule %q: %v\n", what.runner.Filename, runError)
43+
return nil, fmt.Errorf("Failed to generate risks for custom risk rule %q: %v\n", what.runner.Filename, runError)
4544
}
4645

47-
return generatedRisks
46+
return generatedRisks, nil
4847
}
4948

5049
func LoadCustomRiskRules(pluginFiles []string, reporter types.ProgressReporter) risks.RiskRules {

pkg/model/read.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ func ReadAndAnalyzeModel(config *common.Config, progressReporter types.ProgressR
4343
return nil, fmt.Errorf("unable to parse model yaml: %v", parseError)
4444
}
4545

46+
/**
47+
jsonData, _ := json.MarshalIndent(parsedModel, "", " ")
48+
_ = os.WriteFile("parsed-model.json", jsonData, 0600)
49+
50+
yamlData, _ := yaml.Marshal(parsedModel)
51+
_ = os.WriteFile("parsed-model.yaml", yamlData, 0600)
52+
/**/
53+
4654
introTextRAA := applyRAA(parsedModel, config.PluginFolder, config.RAAPlugin, progressReporter)
4755

4856
applyRiskGeneration(parsedModel, builtinRiskRules.Merge(customRiskRules), config.SkipRiskRules, progressReporter)
@@ -56,14 +64,6 @@ func ReadAndAnalyzeModel(config *common.Config, progressReporter types.ProgressR
5664
return nil, fmt.Errorf("unable to check risk tracking: %v", err)
5765
}
5866

59-
/*
60-
jsonData, _ := json.MarshalIndent(parsedModel, "", " ")
61-
_ = os.WriteFile("parsed-model.json", jsonData, 0600)
62-
63-
yamlData, _ := yaml.Marshal(parsedModel)
64-
_ = os.WriteFile("parsed-model.yaml", yamlData, 0600)
65-
*/
66-
6767
return &ReadResult{
6868
ModelInput: modelInput,
6969
ParsedModel: parsedModel,
@@ -94,7 +94,12 @@ func applyRiskGeneration(parsedModel *types.Model, rules risks.RiskRules,
9494
}
9595

9696
parsedModel.AddToListOfSupportedTags(rule.SupportedTags())
97-
newRisks := rule.GenerateRisks(parsedModel)
97+
newRisks, riskError := rule.GenerateRisks(parsedModel)
98+
if riskError != nil {
99+
progressReporter.Warnf("Error generating risks for %q: %v", id, riskError)
100+
continue
101+
}
102+
98103
if len(newRisks) > 0 {
99104
parsedModel.GeneratedRisksByCategory[id] = newRisks
100105
}

pkg/script/common/key-words.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package common
22

33
const (
4-
Risk = "risk"
5-
Match = "match"
6-
Utils = "utils"
4+
Script = "script"
5+
Risk = "risk"
6+
Match = "match"
7+
Utils = "utils"
78

89
Assign = "assign"
910
Loop = "loop"

pkg/script/common/scope.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,37 @@ type Scope struct {
1616
returnValue Value
1717
}
1818

19-
func (what *Scope) Init(model *types.Model, risk *types.RiskCategory, methods map[string]Statement) error {
20-
if model != nil {
21-
data, marshalError := json.Marshal(model)
19+
func (what *Scope) Init(risk *types.RiskCategory, methods map[string]Statement) error {
20+
if risk != nil {
21+
data, marshalError := json.Marshal(risk)
2222
if marshalError != nil {
2323
return marshalError
2424
}
2525

26-
unmarshalError := json.Unmarshal(data, &what.Model)
26+
unmarshalError := json.Unmarshal(data, &what.Risk)
2727
if unmarshalError != nil {
2828
return unmarshalError
2929
}
3030
}
3131

32-
if risk != nil {
33-
data, marshalError := json.Marshal(risk)
32+
what.Methods = methods
33+
34+
return nil
35+
}
36+
37+
func (what *Scope) SetModel(model *types.Model) error {
38+
if model != nil {
39+
data, marshalError := json.Marshal(model)
3440
if marshalError != nil {
3541
return marshalError
3642
}
3743

38-
unmarshalError := json.Unmarshal(data, &what.Risk)
44+
unmarshalError := json.Unmarshal(data, &what.Model)
3945
if unmarshalError != nil {
4046
return unmarshalError
4147
}
4248
}
4349

44-
what.Methods = methods
45-
4650
return nil
4751
}
4852

0 commit comments

Comments
 (0)