diff --git a/pkg/model/read.go b/pkg/model/read.go index 8259a18c..cf466918 100644 --- a/pkg/model/read.go +++ b/pkg/model/read.go @@ -1,7 +1,10 @@ package model import ( + "encoding/json" "fmt" + "gopkg.in/yaml.v3" + "os" "path/filepath" "strings" @@ -43,7 +46,7 @@ func ReadAndAnalyzeModel(config *common.Config, progressReporter types.ProgressR return nil, fmt.Errorf("unable to parse model yaml: %v", parseError) } - /** + /**/ jsonData, _ := json.MarshalIndent(parsedModel, "", " ") _ = os.WriteFile("parsed-model.json", jsonData, 0600) diff --git a/pkg/security/risks/builtin/missing-vault-rule.go b/pkg/security/risks/builtin/missing-vault-rule.go index b1db3a50..042317d2 100644 --- a/pkg/security/risks/builtin/missing-vault-rule.go +++ b/pkg/security/risks/builtin/missing-vault-rule.go @@ -61,7 +61,7 @@ func (r *MissingVaultRule) GenerateRisks(input *types.Model) ([]*types.Risk, err impact = types.MediumImpact } // just for referencing the most interesting asset - if mostRelevantAsset != nil && techAsset.HighestSensitivityScore() > mostRelevantAsset.HighestSensitivityScore() { + if mostRelevantAsset == nil || techAsset.HighestSensitivityScore() > mostRelevantAsset.HighestSensitivityScore() { mostRelevantAsset = techAsset } } @@ -72,7 +72,10 @@ func (r *MissingVaultRule) GenerateRisks(input *types.Model) ([]*types.Risk, err } func (r *MissingVaultRule) createRisk(technicalAsset *types.TechnicalAsset, impact types.RiskExploitationImpact) *types.Risk { - title := "Missing Vault (Secret Storage) in the threat model (referencing asset " + technicalAsset.Title + " as an example)" + title := "Missing Vault (Secret Storage) in the threat model" + if technicalAsset != nil { + title += " (referencing asset " + technicalAsset.Title + " as an example)" + } risk := &types.Risk{ CategoryId: r.Category().ID, Severity: types.CalculateSeverity(types.Unlikely, impact), diff --git a/pkg/security/types/communication_link.go b/pkg/security/types/communication_link.go index 82f67855..8e2ccda1 100644 --- a/pkg/security/types/communication_link.go +++ b/pkg/security/types/communication_link.go @@ -50,18 +50,24 @@ func (what CommunicationLink) IsAcrossTrustBoundary(parsedModel *Model) bool { func (what CommunicationLink) IsAcrossTrustBoundaryNetworkOnly(parsedModel *Model) bool { trustBoundaryOfSourceAsset, trustBoundaryOfSourceAssetOk := parsedModel.DirectContainingTrustBoundaryMappedByTechnicalAssetId[what.SourceId] - if !trustBoundaryOfSourceAssetOk || !trustBoundaryOfSourceAsset.Type.IsNetworkBoundary() { // find and use the parent boundary then + if !trustBoundaryOfSourceAssetOk { + return false + } + if !trustBoundaryOfSourceAsset.Type.IsNetworkBoundary() { // find and use the parent boundary then trustBoundaryOfSourceAsset, trustBoundaryOfSourceAssetOk = parsedModel.TrustBoundaries[trustBoundaryOfSourceAsset.ParentTrustBoundaryID(parsedModel)] + if !trustBoundaryOfSourceAssetOk { + return false + } } trustBoundaryOfTargetAsset, trustBoundaryOfTargetAssetOk := parsedModel.DirectContainingTrustBoundaryMappedByTechnicalAssetId[what.TargetId] - if !trustBoundaryOfTargetAssetOk || !trustBoundaryOfTargetAsset.Type.IsNetworkBoundary() { // find and use the parent boundary then - trustBoundaryOfTargetAsset, trustBoundaryOfTargetAssetOk = parsedModel.TrustBoundaries[trustBoundaryOfTargetAsset.ParentTrustBoundaryID(parsedModel)] - } - if trustBoundaryOfSourceAssetOk != trustBoundaryOfTargetAssetOk { + if !trustBoundaryOfTargetAssetOk { return false } - if !trustBoundaryOfSourceAssetOk && !trustBoundaryOfTargetAssetOk { - return true + if !trustBoundaryOfTargetAsset.Type.IsNetworkBoundary() { // find and use the parent boundary then + trustBoundaryOfTargetAsset, trustBoundaryOfTargetAssetOk = parsedModel.TrustBoundaries[trustBoundaryOfTargetAsset.ParentTrustBoundaryID(parsedModel)] + if !trustBoundaryOfTargetAssetOk { + return false + } } return trustBoundaryOfSourceAsset.Id != trustBoundaryOfTargetAsset.Id && trustBoundaryOfTargetAsset.Type.IsNetworkBoundary() }