diff --git a/pkg/security/risks/builtin/missing_authentication_rule.go b/pkg/security/risks/builtin/missing_authentication_rule.go
index c0be1da9..b66d3006 100644
--- a/pkg/security/risks/builtin/missing_authentication_rule.go
+++ b/pkg/security/risks/builtin/missing_authentication_rule.go
@@ -47,36 +47,39 @@ func (r *MissingAuthenticationRule) GenerateRisks(input *types.Model) ([]*types.
continue
}
- if technicalAsset.HighestProcessedConfidentiality(input) >= types.Confidential ||
- technicalAsset.HighestProcessedIntegrity(input) >= types.Critical ||
- technicalAsset.HighestProcessedAvailability(input) >= types.Critical ||
- technicalAsset.MultiTenant {
- // check each incoming data flow
- commLinks := input.IncomingTechnicalCommunicationLinksMappedByTargetId[technicalAsset.Id]
- for _, commLink := range commLinks {
- caller := input.TechnicalAssets[commLink.SourceId]
- if caller.Technologies.GetAttribute(types.IsUnprotectedCommunicationsTolerated) || caller.Type == types.Datastore {
- continue
- }
- highRisk := commLink.HighestConfidentiality(input) == types.StrictlyConfidential ||
- commLink.HighestIntegrity(input) == types.MissionCritical
- lowRisk := commLink.HighestConfidentiality(input) <= types.Internal &&
- commLink.HighestIntegrity(input) == types.Operational
- impact := types.MediumImpact
- if highRisk {
- impact = types.HighImpact
- } else if lowRisk {
- impact = types.LowImpact
- }
- if commLink.Authentication == types.NoneAuthentication && !commLink.Protocol.IsProcessLocal() {
- risks = append(risks, r.createRisk(input, technicalAsset, commLink, commLink, "", impact, types.Likely, false, r.Category()))
- }
+ if technicalAsset.HighestProcessedConfidentiality(input) < types.Confidential &&
+ technicalAsset.HighestProcessedIntegrity(input) < types.Critical &&
+ technicalAsset.HighestProcessedAvailability(input) < types.Critical &&
+ !technicalAsset.MultiTenant {
+ continue
+ }
+
+ // check each incoming data flow
+ commLinks := input.IncomingTechnicalCommunicationLinksMappedByTargetId[technicalAsset.Id]
+ for _, commLink := range commLinks {
+ caller := input.TechnicalAssets[commLink.SourceId]
+ if caller.Technologies.GetAttribute(types.IsUnprotectedCommunicationsTolerated) || caller.Type == types.Datastore {
+ continue
+ }
+ impact := r.calculateImpact(commLink, input)
+ if commLink.Authentication == types.NoneAuthentication && !commLink.Protocol.IsProcessLocal() {
+ risks = append(risks, r.createRisk(input, technicalAsset, commLink, commLink, "", impact, types.Likely, false, r.Category()))
}
}
}
return risks, nil
}
+func (r *MissingAuthenticationRule) calculateImpact(commLink *types.CommunicationLink, input *types.Model) types.RiskExploitationImpact {
+ if commLink.HighestConfidentiality(input) == types.StrictlyConfidential || commLink.HighestIntegrity(input) == types.MissionCritical {
+ return types.HighImpact
+ }
+ if commLink.HighestConfidentiality(input) <= types.Internal && commLink.HighestIntegrity(input) == types.Operational {
+ return types.LowImpact
+ }
+ return types.MediumImpact
+}
+
func (r *MissingAuthenticationRule) createRisk(input *types.Model, technicalAsset *types.TechnicalAsset, incomingAccess, incomingAccessOrigin *types.CommunicationLink, hopBetween string,
impact types.RiskExploitationImpact, likelihood types.RiskExploitationLikelihood, twoFactor bool, category *types.RiskCategory) *types.Risk {
factorString := ""
diff --git a/pkg/security/risks/builtin/missing_authentication_rule_test.go b/pkg/security/risks/builtin/missing_authentication_rule_test.go
index b2f08544..e0b0bfba 100644
--- a/pkg/security/risks/builtin/missing_authentication_rule_test.go
+++ b/pkg/security/risks/builtin/missing_authentication_rule_test.go
@@ -324,3 +324,43 @@ func TestMissingAuthenticationRuleGenerateRisksOperationalIntegrityRisksCreatedW
assert.Equal(t, "Missing Authentication covering communication link User Access via Browser from User Interface to Test Technical Asset", risks[0].Title)
assert.Equal(t, types.LowImpact, risks[0].ExploitationImpact)
}
+
+func TestMissingAuthenticationRuleGenerateRisksProcessingConfidentialDataRisksCreated(t *testing.T) {
+ rule := NewMissingAuthenticationRule()
+
+ risks, err := rule.GenerateRisks(&types.Model{
+ TechnicalAssets: map[string]*types.TechnicalAsset{
+ "ta1": {
+ Id: "ta1",
+ Title: "Test Technical Asset",
+ DataAssetsProcessed: []string{"confidential"},
+ },
+ "ta2": {
+ Id: "ta2",
+ Title: "User Interface",
+ },
+ },
+ IncomingTechnicalCommunicationLinksMappedByTargetId: map[string][]*types.CommunicationLink{
+ "ta1": {
+ {
+ Title: "User Access via Browser",
+ SourceId: "ta2",
+ Authentication: types.NoneAuthentication,
+ Protocol: types.HTTPS,
+ },
+ },
+ },
+ DataAssets: map[string]*types.DataAsset{
+ "confidential": {
+ Id: "confidential",
+ Title: "Confidential Data",
+ Confidentiality: types.Confidential,
+ },
+ },
+ })
+
+ assert.Nil(t, err)
+ assert.Len(t, risks, 1)
+ assert.Equal(t, "Missing Authentication covering communication link User Access via Browser from User Interface to Test Technical Asset", risks[0].Title)
+ assert.Equal(t, types.MediumImpact, risks[0].ExploitationImpact)
+}