Skip to content

Commit

Permalink
Refactoring to reduce nesting and cover more uncovered use cases
Browse files Browse the repository at this point in the history
  • Loading branch information
Yevhen Zavhorodnii committed May 31, 2024
1 parent 24b7851 commit b6ed478
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 8 deletions.
18 changes: 10 additions & 8 deletions pkg/security/risks/builtin/server_side_request_forgery_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,16 @@ func (r *ServerSideRequestForgeryRule) createRisk(input *types.Model, technicalA
uniqueDataBreachTechnicalAssetIDs := make(map[string]interface{})
uniqueDataBreachTechnicalAssetIDs[technicalAsset.Id] = true
for _, potentialTargetAsset := range input.TechnicalAssets {
if technicalAsset.IsSameTrustBoundaryNetworkOnly(input, potentialTargetAsset.Id) {
for _, commLinkIncoming := range input.IncomingTechnicalCommunicationLinksMappedByTargetId[potentialTargetAsset.Id] {
if commLinkIncoming.Protocol.IsPotentialWebAccessProtocol() {
uniqueDataBreachTechnicalAssetIDs[potentialTargetAsset.Id] = true
if potentialTargetAsset.HighestProcessedConfidentiality(input) == types.StrictlyConfidential {
impact = types.MediumImpact
}
}
if !technicalAsset.IsSameTrustBoundaryNetworkOnly(input, potentialTargetAsset.Id) {
continue
}
for _, commLinkIncoming := range input.IncomingTechnicalCommunicationLinksMappedByTargetId[potentialTargetAsset.Id] {
if !commLinkIncoming.Protocol.IsPotentialWebAccessProtocol() {
continue
}
uniqueDataBreachTechnicalAssetIDs[potentialTargetAsset.Id] = true
if potentialTargetAsset.HighestProcessedConfidentiality(input) == types.StrictlyConfidential {
impact = types.MediumImpact
}
}
}
Expand Down
135 changes: 135 additions & 0 deletions pkg/security/risks/builtin/server_side_request_forgery_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,67 @@ func TestServerSideRequestForgeryRuleGenerateRisksStrictlyConfidentialTrustBound
assert.Equal(t, "<b>Server-Side Request Forgery (SSRF)</b> risk at <b>Test Technical Asset</b> server-side web-requesting the target <b>Test Target Asset</b> via <b>Test Communication Link</b>", risks[0].Title)
}

func TestServerSideRequestForgeryRuleGenerateRisksStrictlyConfidentialDifferentTrustBoundaryNotCloudLowImpactRisksCreated(t *testing.T) {
rule := NewServerSideRequestForgeryRule()
tb1 := &types.TrustBoundary{
Id: "tb1",
Type: types.NetworkVirtualLAN,
TechnicalAssetsInside: []string{"ta1"},
}
tb2 := &types.TrustBoundary{
Id: "tb2",
Type: types.NetworkVirtualLAN,
TechnicalAssetsInside: []string{"ta2"},
}
comm := &types.CommunicationLink{
Protocol: types.HTTP,
TargetId: "ta2",
Title: "Test Communication Link",
}
risks, err := rule.GenerateRisks(&types.Model{
TechnicalAssets: map[string]*types.TechnicalAsset{
"ta1": {
Id: "ta1",
Title: "Test Technical Asset",
OutOfScope: false,
Technologies: types.TechnologyList{
{
Name: "service-registry",
Attributes: map[string]bool{
types.IsClient: false,
types.LoadBalancer: false,
},
},
},
CommunicationLinks: []*types.CommunicationLink{comm},
},
"ta2": {
Id: "ta2",
Title: "Test Target Asset",
OutOfScope: false,
Confidentiality: types.Confidential,
},
},
IncomingTechnicalCommunicationLinksMappedByTargetId: map[string][]*types.CommunicationLink{
"ta2": {comm},
},
TrustBoundaries: map[string]*types.TrustBoundary{
"tb1": tb1,
"tb2": tb2,
},
DirectContainingTrustBoundaryMappedByTechnicalAssetId: map[string]*types.TrustBoundary{
"ta1": tb1,
"ta2": tb2,
},
})

assert.Nil(t, err)
assert.Len(t, risks, 1)
assert.Equal(t, types.LowImpact, risks[0].ExploitationImpact)
assert.Equal(t, types.Likely, risks[0].ExploitationLikelihood)
assert.Equal(t, "<b>Server-Side Request Forgery (SSRF)</b> risk at <b>Test Technical Asset</b> server-side web-requesting the target <b>Test Target Asset</b> via <b>Test Communication Link</b>", risks[0].Title)
}

func TestServerSideRequestForgeryRuleGenerateRisksWithinDevopsUnlikelyLikelihoodRisksCreated(t *testing.T) {
rule := NewServerSideRequestForgeryRule()
risks, err := rule.GenerateRisks(&types.Model{
Expand Down Expand Up @@ -352,3 +413,77 @@ func TestServerSideRequestForgeryRuleGenerateRisksWithinDevopsUnlikelyLikelihood
assert.Equal(t, types.Unlikely, risks[0].ExploitationLikelihood)
assert.Equal(t, "<b>Server-Side Request Forgery (SSRF)</b> risk at <b>Test Technical Asset</b> server-side web-requesting the target <b>Test Target Asset</b> via <b>Test Communication Link</b>", risks[0].Title)
}

func TestServerSideRequestForgeryRuleGenerateRisksStrictlyConfidentialNotHttpAccessDifferentTrustBoundaryNotCloudLowImpactRisksCreated(t *testing.T) {
rule := NewServerSideRequestForgeryRule()
tb1 := &types.TrustBoundary{
Id: "tb1",
Type: types.NetworkVirtualLAN,
TechnicalAssetsInside: []string{"ta1"},
}
tb2 := &types.TrustBoundary{
Id: "tb2",
Type: types.NetworkVirtualLAN,
TechnicalAssetsInside: []string{"ta2", "ta3"},
}
comm := &types.CommunicationLink{
Protocol: types.HTTP,
TargetId: "ta2",
Title: "Test Communication Link",
}
comm2 := &types.CommunicationLink{
Protocol: types.SqlAccessProtocol,
TargetId: "ta1",
Title: "Test Communication Link 2",
}
risks, err := rule.GenerateRisks(&types.Model{
TechnicalAssets: map[string]*types.TechnicalAsset{
"ta1": {
Id: "ta1",
Title: "Test Technical Asset",
OutOfScope: false,
Technologies: types.TechnologyList{
{
Name: "service-registry",
Attributes: map[string]bool{
types.IsClient: false,
types.LoadBalancer: false,
},
},
},
CommunicationLinks: []*types.CommunicationLink{comm, comm2},
},
"ta2": {
Id: "ta2",
Title: "Test Target Asset",
OutOfScope: false,
Confidentiality: types.Confidential,
},
"ta3": {
Id: "ta3",
Title: "Test Source Asset",
OutOfScope: false,
Confidentiality: types.StrictlyConfidential,
},
},
IncomingTechnicalCommunicationLinksMappedByTargetId: map[string][]*types.CommunicationLink{
"ta2": {comm},
"ta1": {comm2},
},
TrustBoundaries: map[string]*types.TrustBoundary{
"tb1": tb1,
"tb2": tb2,
},
DirectContainingTrustBoundaryMappedByTechnicalAssetId: map[string]*types.TrustBoundary{
"ta1": tb1,
"ta2": tb2,
"ta3": tb2,
},
})

assert.Nil(t, err)
assert.Len(t, risks, 1)
assert.Equal(t, types.LowImpact, risks[0].ExploitationImpact)
assert.Equal(t, types.Likely, risks[0].ExploitationLikelihood)
assert.Equal(t, "<b>Server-Side Request Forgery (SSRF)</b> risk at <b>Test Technical Asset</b> server-side web-requesting the target <b>Test Target Asset</b> via <b>Test Communication Link</b>", risks[0].Title)
}

0 comments on commit b6ed478

Please sign in to comment.