Skip to content

Commit

Permalink
made risk rules use attributes instead of hardcoded technology types
Browse files Browse the repository at this point in the history
  • Loading branch information
joreiche committed Mar 27, 2024
1 parent 1141d7d commit f998e38
Show file tree
Hide file tree
Showing 53 changed files with 479 additions and 1,212 deletions.
21 changes: 10 additions & 11 deletions cmd/raa/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,35 +182,34 @@ func calculateAttackerAttractiveness(input *types.ParsedModel, techAsset types.T
score += dataAsset.Integrity.AttackerAttractivenessForInOutTransferredData() * dataAsset.Quantity.QuantityFactor()
score += dataAsset.Availability.AttackerAttractivenessForInOutTransferredData()
}

for _, dataAssetReceived := range dataFlow.DataAssetsReceived {
dataAsset := input.DataAssets[dataAssetReceived]
score += dataAsset.Confidentiality.AttackerAttractivenessForInOutTransferredData() * dataAsset.Quantity.QuantityFactor()
score += dataAsset.Integrity.AttackerAttractivenessForInOutTransferredData() * dataAsset.Quantity.QuantityFactor()
score += dataAsset.Availability.AttackerAttractivenessForInOutTransferredData()
}
}
if techAsset.Technologies.HasAnyType(types.LoadBalancer, types.ReverseProxy) {

if techAsset.Technologies.GetAttribute(types.LoadBalancer, types.ReverseProxy) {
score = score / 5.5
}
if techAsset.Technologies.HasAnyType(types.Monitoring) {
} else if techAsset.Technologies.GetAttribute(types.Monitoring) {
score = score / 5
}
if techAsset.Technologies.HasAnyType(types.ContainerPlatform) {
} else if techAsset.Technologies.GetAttribute(types.ContainerPlatform) {
score = score * 5
}
if techAsset.Technologies.HasAnyType(types.Vault) {
} else if techAsset.Technologies.GetAttribute(types.Vault) {
score = score * 2
}
if techAsset.Technologies.HasAnyType(types.BuildPipeline, types.SourcecodeRepository, types.ArtifactRegistry) {
} else if techAsset.Technologies.GetAttribute(types.BuildPipeline, types.SourcecodeRepository, types.ArtifactRegistry) {
score = score * 2
}
if techAsset.Technologies.HasAnyType(types.IdentityProvider, types.IdentityStoreDatabase, types.IdentityStoreLDAP) {
} else if techAsset.Technologies.GetAttribute(types.IdentityProvider, types.IdentityStoreDatabase, types.IdentityStoreLDAP) {
score = score * 2.5
} else if techAsset.Type == types.Datastore {
score = score * 2
}

if techAsset.MultiTenant {
score = score * 1.5
}

return score
}
48 changes: 27 additions & 21 deletions cmd/tech_conv/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,48 @@ import (
)

func main() {
save := flag.Bool("save", false, "Save all technologies to technologies.yaml")
// save := flag.Bool("save", false, "Save all technologies to technologies.yaml")
load := flag.Bool("load", false, "Load all technologies from technologies.yaml")
comp := flag.Bool("comp", false, "Compare all technologies from technologies.yaml to types.TechnicalAssetTechnologyValues()")
// comp := flag.Bool("comp", false, "Compare all technologies from technologies.yaml to types.TechnicalAssetTechnologyValues()")
flag.Parse()

filename := flag.Arg(0)
if filename == "" {
filename = "technologies.yaml"
}

if *save {
saveError := getTechnologies().Save(filename)
if saveError != nil {
fmt.Printf("error saving technologies: %v\n", saveError)
return
/*
if *save {
saveError := getTechnologies().Save(filename)
if saveError != nil {
fmt.Printf("error saving technologies: %v\n", saveError)
return
}
}
}
*/

if *load {
technologies := make(types.TechnologyMap)
loadError := technologies.Load(filename)
loadError := technologies.LoadFromFile(filename)
if loadError != nil {
fmt.Printf("error loading technologies: %v\n", loadError)
return
}
}

if *comp {
savedTechnologies := make(types.TechnologyMap)
loadError := savedTechnologies.Load(filename)
if loadError != nil {
fmt.Printf("error loading technologies: %v\n", loadError)
return
}
/*
if *comp {
savedTechnologies := make(types.TechnologyMap)
loadError := savedTechnologies.LoadFromFile(filename)
if loadError != nil {
fmt.Printf("error loading technologies: %v\n", loadError)
return
}
savedTechnologies.PropagateAttributes()
compareTechnologies(savedTechnologies, getTechnologies())
}
savedTechnologies.PropagateAttributes()
compareTechnologies(savedTechnologies, getTechnologies())
}
*/
}

func compareTechnologies(savedTechnologies types.TechnologyMap, builtinTechnologies types.TechnologyMap) {

Check failure on line 55 in cmd/tech_conv/main.go

View workflow job for this annotation

GitHub Actions / lint

func `compareTechnologies` is unused (unused)
Expand Down Expand Up @@ -161,6 +165,7 @@ func compareTechnology(savedTechnology types.Technology, builtinTechnology types
return diffs
}

/*
func getTechnologies() types.TechnologyMap {
technologies := make(types.TechnologyMap)
for _, value := range types.TechnicalAssetTechnologyValues() {
Expand All @@ -172,11 +177,11 @@ func getTechnologies() types.TechnologyMap {
Attributes: make(map[string]bool),
}
if tech.IsWebApplication() {
if tech..GetAttribute(types.WebApplication) {
technology.Attributes["web_application"] = true
}
if tech.IsWebService() {
if tech.GetAttribute(IsWebService) {
technology.Attributes["web_service"] = true
}
Expand Down Expand Up @@ -245,3 +250,4 @@ func getTechnologies() types.TechnologyMap {
return technologies
}
*/
2 changes: 1 addition & 1 deletion internal/threagile/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func (what *Threagile) initAnalyze() *Threagile {
commands := what.readCommands()
progressReporter := common.DefaultProgressReporter{Verbose: cfg.Verbose}

r, err := model.ReadAndAnalyzeModel(*cfg, progressReporter)
r, err := model.ReadAndAnalyzeModel(cfg, progressReporter)
if err != nil {
return fmt.Errorf("failed to read and analyze model: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/threagile/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (what *Threagile) initExecute() *Threagile {
cfg := what.readConfig(cmd, what.buildTimestamp)
progressReporter := common.DefaultProgressReporter{Verbose: cfg.Verbose}

r, err := model.ReadAndAnalyzeModel(*cfg, progressReporter)
r, err := model.ReadAndAnalyzeModel(cfg, progressReporter)
if err != nil {
return fmt.Errorf("unable to read and analyze model: %v", err)
}
Expand Down
4 changes: 2 additions & 2 deletions internal/threagile/explain.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (what *Threagile) initExplainNew() *Threagile {

// todo: reuse model if already loaded

result, runError := model.ReadAndAnalyzeModel(*cfg, progressReporter)
result, runError := model.ReadAndAnalyzeModel(cfg, progressReporter)
if runError != nil {
cmd.Printf("Failed to read and analyze model: %v", runError)
return runError
Expand Down Expand Up @@ -110,7 +110,7 @@ func (what *Threagile) initExplainNew() *Threagile {
cmd.Println()
cmd.Println("The following types are available (can be extended for custom rules):")
cmd.Println()
for name, values := range types.GetBuiltinTypeValues() {
for name, values := range types.GetBuiltinTypeValues(what.readConfig(cmd, what.buildTimestamp)) {
cmd.Println(name)
for _, candidate := range values {
cmd.Printf("\t %v: %v\n", candidate, candidate.Explain())
Expand Down
2 changes: 1 addition & 1 deletion internal/threagile/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (what *Threagile) initList() *Threagile {
cmd.Println()
cmd.Println("The following types are available (can be extended for custom rules):")
cmd.Println()
for name, values := range types.GetBuiltinTypeValues() {
for name, values := range types.GetBuiltinTypeValues(what.readConfig(cmd, what.buildTimestamp)) {
cmd.Println(fmt.Sprintf(" %v: %v", name, values))
}
},
Expand Down
26 changes: 13 additions & 13 deletions pkg/macros/add-build-pipeline-macro.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (m *AddBuildPipeline) GetNextQuestion(model *types.ParsedModel) (nextQuesti
}, nil
case 4:
return MacroQuestion{
ID: "code-inspection-platform",
ID: types.CodeInspectionPlatform,
Title: "What product is used as the code inspection platform?",
Description: "This name affects the technical asset's title and ID plus also the tags used.",
PossibleAnswers: nil,
Expand Down Expand Up @@ -280,7 +280,7 @@ func (m *AddBuildPipeline) applyChange(modelInput *input.Model, parsedModel *typ
modelInput.AddTagToModelInput(m.macroState["container-platform"][0], dryRun, changeLogCollector)
}
if m.codeInspectionUsed {
modelInput.AddTagToModelInput(m.macroState["code-inspection-platform"][0], dryRun, changeLogCollector)
modelInput.AddTagToModelInput(m.macroState[types.CodeInspectionPlatform][0], dryRun, changeLogCollector)
}

sourceRepoID := types.MakeID(m.macroState["source-repository"][0]) + "-sourcecode-repository"
Expand All @@ -294,7 +294,7 @@ func (m *AddBuildPipeline) applyChange(modelInput *input.Model, parsedModel *typ
}
codeInspectionPlatformID := ""
if m.codeInspectionUsed {
codeInspectionPlatformID = types.MakeID(m.macroState["code-inspection-platform"][0]) + "-code-inspection-platform"
codeInspectionPlatformID = types.MakeID(m.macroState[types.CodeInspectionPlatform][0]) + "-code-inspection-platform"
}
owner := m.macroState["owner"][0]

Expand Down Expand Up @@ -461,7 +461,7 @@ func (m *AddBuildPipeline) applyChange(modelInput *input.Model, parsedModel *typ
OutOfScope: true,
JustificationOutOfScope: "Development client is not directly in-scope of the application.",
Size: types.System.String(),
Technology: types.DevOpsClient.String(),
Technology: types.DevOpsClient,
Tags: []string{},
Internet: strings.EqualFold(m.macroState["internet"][0], "yes"),
Machine: types.Physical.String(),
Expand Down Expand Up @@ -503,7 +503,7 @@ func (m *AddBuildPipeline) applyChange(modelInput *input.Model, parsedModel *typ
OutOfScope: false,
JustificationOutOfScope: "",
Size: types.Service.String(),
Technology: types.SourcecodeRepository.String(),
Technology: types.SourcecodeRepository,
Tags: []string{input.NormalizeTag(m.macroState["source-repository"][0])},
Internet: strings.EqualFold(m.macroState["internet"][0], "yes"),
Machine: types.Virtual.String(),
Expand Down Expand Up @@ -546,7 +546,7 @@ func (m *AddBuildPipeline) applyChange(modelInput *input.Model, parsedModel *typ
OutOfScope: false,
JustificationOutOfScope: "",
Size: types.Service.String(),
Technology: types.ArtifactRegistry.String(),
Technology: types.ArtifactRegistry,
Tags: []string{input.NormalizeTag(m.macroState["container-registry"][0])},
Internet: strings.EqualFold(m.macroState["internet"][0], "yes"),
Machine: types.Virtual.String(),
Expand Down Expand Up @@ -588,7 +588,7 @@ func (m *AddBuildPipeline) applyChange(modelInput *input.Model, parsedModel *typ
OutOfScope: false,
JustificationOutOfScope: "",
Size: types.System.String(),
Technology: types.ContainerPlatform.String(),
Technology: types.ContainerPlatform,
Tags: []string{input.NormalizeTag(m.macroState["container-platform"][0])},
Internet: strings.EqualFold(m.macroState["internet"][0], "yes"),
Machine: types.Virtual.String(),
Expand Down Expand Up @@ -841,7 +841,7 @@ func (m *AddBuildPipeline) applyChange(modelInput *input.Model, parsedModel *typ
OutOfScope: false,
JustificationOutOfScope: "",
Size: types.Service.String(),
Technology: types.BuildPipeline.String(),
Technology: types.BuildPipeline,
Tags: []string{input.NormalizeTag(m.macroState["build-pipeline"][0])},
Internet: strings.EqualFold(m.macroState["internet"][0], "yes"),
Machine: types.Virtual.String(),
Expand Down Expand Up @@ -883,7 +883,7 @@ func (m *AddBuildPipeline) applyChange(modelInput *input.Model, parsedModel *typ
OutOfScope: false,
JustificationOutOfScope: "",
Size: types.Service.String(),
Technology: types.ArtifactRegistry.String(),
Technology: types.ArtifactRegistry,
Tags: []string{input.NormalizeTag(m.macroState["artifact-registry"][0])},
Internet: strings.EqualFold(m.macroState["internet"][0], "yes"),
Machine: types.Virtual.String(),
Expand Down Expand Up @@ -919,15 +919,15 @@ func (m *AddBuildPipeline) applyChange(modelInput *input.Model, parsedModel *typ
}
techAsset := input.TechnicalAsset{
ID: id,
Description: m.macroState["code-inspection-platform"][0] + " Code Inspection Platform",
Description: m.macroState[types.CodeInspectionPlatform][0] + " Code Inspection Platform",
Type: types.Process.String(),
Usage: types.DevOps.String(),
UsedAsClientByHuman: false,
OutOfScope: false,
JustificationOutOfScope: "",
Size: types.Service.String(),
Technology: types.CodeInspectionPlatform.String(),
Tags: []string{input.NormalizeTag(m.macroState["code-inspection-platform"][0])},
Technology: types.CodeInspectionPlatform,
Tags: []string{input.NormalizeTag(m.macroState[types.CodeInspectionPlatform][0])},
Internet: strings.EqualFold(m.macroState["internet"][0], "yes"),
Machine: types.Virtual.String(),
Encryption: encryption,
Expand All @@ -947,7 +947,7 @@ func (m *AddBuildPipeline) applyChange(modelInput *input.Model, parsedModel *typ
}
*changeLogCollector = append(*changeLogCollector, "adding technical asset (including communication links): "+id)
if !dryRun {
modelInput.TechnicalAssets[m.macroState["code-inspection-platform"][0]+" Code Inspection Platform"] = techAsset
modelInput.TechnicalAssets[m.macroState[types.CodeInspectionPlatform][0]+" Code Inspection Platform"] = techAsset
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/macros/add-vault-macro.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,9 @@ func (m *AddVaultMacro) applyChange(modelInput *input.Model, parsedModel *types.
storageID := "vault-storage"

if databaseUsed || filesystemUsed {
tech := types.FileServer.String() // TODO ask for local or remote and only local use execution-environment (and add separate tech type LocalFilesystem?)
tech := types.FileServer // TODO ask for local or remote and only local use execution-environment (and add separate tech type LocalFilesystem?)
if databaseUsed {
tech = types.Database.String()
tech = types.Database
}
if _, exists := parsedModel.TechnicalAssets[storageID]; !exists {
serverSideTechAssets = append(serverSideTechAssets, storageID)
Expand Down Expand Up @@ -347,7 +347,7 @@ func (m *AddVaultMacro) applyChange(modelInput *input.Model, parsedModel *types.
OutOfScope: false,
JustificationOutOfScope: "",
Size: types.Service.String(),
Technology: types.Vault.String(),
Technology: types.Vault,
Tags: []string{input.NormalizeTag(m.macroState["vault-name"][0])},
Internet: false,
Machine: types.Virtual.String(),
Expand Down
2 changes: 1 addition & 1 deletion pkg/model/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"time"
)

func ParseModel(config common.Config, modelInput *input.Model, builtinRiskRules map[string]risks.RiskRule, customRiskRules map[string]*CustomRisk) (*types.ParsedModel, error) {
func ParseModel(config *common.Config, modelInput *input.Model, builtinRiskRules map[string]risks.RiskRule, customRiskRules map[string]*CustomRisk) (*types.ParsedModel, error) {
technologies := make(types.TechnologyMap)
technologiesLoadError := technologies.LoadWithConfig(config, "technologies.yaml")
if technologiesLoadError != nil {
Expand Down
14 changes: 7 additions & 7 deletions pkg/model/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

func TestDefaultInputNotFail(t *testing.T) {
parsedModel, err := ParseModel(common.Config{}, createInputModel(make(map[string]input.TechnicalAsset), make(map[string]input.DataAsset)), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))
parsedModel, err := ParseModel(&common.Config{}, createInputModel(make(map[string]input.TechnicalAsset), make(map[string]input.DataAsset)), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))

assert.NoError(t, err)
assert.NotNil(t, parsedModel)
Expand All @@ -27,7 +27,7 @@ func TestInferConfidentiality_NotSet_NoOthers_ExpectTODO(t *testing.T) {
ta := make(map[string]input.TechnicalAsset)
da := make(map[string]input.DataAsset)

_, err := ParseModel(common.Config{}, createInputModel(ta, da), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))
_, err := ParseModel(&common.Config{}, createInputModel(ta, da), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))
// TODO: rename test and check if everyone agree that by default it should be public if there are no other assets

assert.NoError(t, err)
Expand Down Expand Up @@ -58,7 +58,7 @@ func TestInferConfidentiality_ExpectHighestConfidentiality(t *testing.T) {
taWithPublicConfidentialityDataAsset.DataAssetsProcessed = append(taWithPublicConfidentialityDataAsset.DataAssetsProcessed, daPublicConfidentiality.ID)
ta[taWithPublicConfidentialityDataAsset.ID] = taWithPublicConfidentialityDataAsset

parsedModel, err := ParseModel(common.Config{}, createInputModel(ta, da), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))
parsedModel, err := ParseModel(&common.Config{}, createInputModel(ta, da), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))

assert.NoError(t, err)
assert.Equal(t, types.Confidential, parsedModel.TechnicalAssets[taWithConfidentialConfidentialityDataAsset.ID].Confidentiality)
Expand All @@ -70,7 +70,7 @@ func TestInferIntegrity_NotSet_NoOthers_ExpectTODO(t *testing.T) {
ta := make(map[string]input.TechnicalAsset)
da := make(map[string]input.DataAsset)

_, err := ParseModel(common.Config{}, createInputModel(ta, da), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))
_, err := ParseModel(&common.Config{}, createInputModel(ta, da), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))
// TODO: rename test and check if everyone agree that by default it should be public if there are no other assets

assert.NoError(t, err)
Expand Down Expand Up @@ -101,7 +101,7 @@ func TestInferIntegrity_ExpectHighestIntegrity(t *testing.T) {
taWithArchiveIntegrityDataAsset.DataAssetsProcessed = append(taWithArchiveIntegrityDataAsset.DataAssetsProcessed, daArchiveIntegrity.ID)
ta[taWithArchiveIntegrityDataAsset.ID] = taWithArchiveIntegrityDataAsset

parsedModel, err := ParseModel(common.Config{}, createInputModel(ta, da), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))
parsedModel, err := ParseModel(&common.Config{}, createInputModel(ta, da), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))

assert.NoError(t, err)
assert.Equal(t, types.Critical, parsedModel.TechnicalAssets[taWithCriticalIntegrityDataAsset.ID].Integrity)
Expand All @@ -113,7 +113,7 @@ func TestInferAvailability_NotSet_NoOthers_ExpectTODO(t *testing.T) {
ta := make(map[string]input.TechnicalAsset)
da := make(map[string]input.DataAsset)

_, err := ParseModel(common.Config{}, createInputModel(ta, da), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))
_, err := ParseModel(&common.Config{}, createInputModel(ta, da), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))

assert.NoError(t, err)
}
Expand Down Expand Up @@ -143,7 +143,7 @@ func TestInferAvailability_ExpectHighestAvailability(t *testing.T) {
taWithArchiveAvailabilityDataAsset.DataAssetsProcessed = append(taWithArchiveAvailabilityDataAsset.DataAssetsProcessed, daArchiveAvailability.ID)
ta[taWithArchiveAvailabilityDataAsset.ID] = taWithArchiveAvailabilityDataAsset

parsedModel, err := ParseModel(common.Config{}, createInputModel(ta, da), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))
parsedModel, err := ParseModel(&common.Config{}, createInputModel(ta, da), make(map[string]risks.RiskRule), make(map[string]*CustomRisk))

assert.NoError(t, err)
assert.Equal(t, types.Critical, parsedModel.TechnicalAssets[taWithCriticalAvailabilityDataAsset.ID].Availability)
Expand Down
2 changes: 1 addition & 1 deletion pkg/model/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (what ReadResult) ExplainRisk(cfg *common.Config, risk string, reporter com

// TODO: consider about splitting this function into smaller ones for better reusability

func ReadAndAnalyzeModel(config common.Config, progressReporter types.ProgressReporter) (*ReadResult, error) {
func ReadAndAnalyzeModel(config *common.Config, progressReporter types.ProgressReporter) (*ReadResult, error) {
progressReporter.Infof("Writing into output directory: %v", config.OutputFolder)
progressReporter.Infof("Parsing model: %v", config.InputFile)

Expand Down
Loading

0 comments on commit f998e38

Please sign in to comment.