-
Notifications
You must be signed in to change notification settings - Fork 129
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cover search query injection rule with unit tests
- Loading branch information
Yevhen Zavhorodnii
committed
May 31, 2024
1 parent
cd9d2e1
commit 6406045
Showing
1 changed file
with
285 additions
and
0 deletions.
There are no files selected for viewing
285 changes: 285 additions & 0 deletions
285
pkg/security/risks/builtin/search_query_injection_rule_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,285 @@ | ||
package builtin | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/threagile/threagile/pkg/security/types" | ||
) | ||
|
||
func TestSearchQueryInjectionRuleGenerateRisksEmptyModelNotRisksCreated(t *testing.T) { | ||
rule := NewSearchQueryInjectionRule() | ||
|
||
risks, err := rule.GenerateRisks(&types.Model{}) | ||
|
||
assert.Nil(t, err) | ||
assert.Empty(t, risks) | ||
} | ||
|
||
func TestSearchQueryInjectionRuleGenerateRisksOutOfScopeNoRisksCreated(t *testing.T) { | ||
rule := NewSearchQueryInjectionRule() | ||
risks, err := rule.GenerateRisks(&types.Model{ | ||
TechnicalAssets: map[string]*types.TechnicalAsset{ | ||
"ta1": { | ||
Title: "Test Technical Asset", | ||
OutOfScope: true, | ||
Technologies: types.TechnologyList{ | ||
{ | ||
Name: "service-registry", | ||
Attributes: map[string]bool{ | ||
types.IsSearchRelated: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}) | ||
|
||
assert.Nil(t, err) | ||
assert.Empty(t, risks) | ||
} | ||
|
||
func TestSearchQueryInjectionRuleGenerateRisksNotSearchRelatedNoRisksCreated(t *testing.T) { | ||
rule := NewSearchQueryInjectionRule() | ||
risks, err := rule.GenerateRisks(&types.Model{ | ||
TechnicalAssets: map[string]*types.TechnicalAsset{ | ||
"ta1": { | ||
Title: "Test Technical Asset", | ||
OutOfScope: false, | ||
Technologies: types.TechnologyList{ | ||
{ | ||
Name: "service-registry", | ||
Attributes: map[string]bool{ | ||
types.IsSearchRelated: false, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}) | ||
|
||
assert.Nil(t, err) | ||
assert.Empty(t, risks) | ||
} | ||
|
||
func TestSearchQueryInjectionRuleGenerateRisksNoIncomingCommunicationLinkNoRisksCreated(t *testing.T) { | ||
rule := NewSearchQueryInjectionRule() | ||
risks, err := rule.GenerateRisks(&types.Model{ | ||
TechnicalAssets: map[string]*types.TechnicalAsset{ | ||
"ta1": { | ||
Title: "Test Technical Asset", | ||
OutOfScope: false, | ||
Technologies: types.TechnologyList{ | ||
{ | ||
Name: "service-registry", | ||
Attributes: map[string]bool{ | ||
types.IsSearchRelated: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}) | ||
|
||
assert.Nil(t, err) | ||
assert.Empty(t, risks) | ||
} | ||
|
||
func TestSearchQueryInjectionRuleGenerateRisksCallerOutOfScopeNoRisksCreated(t *testing.T) { | ||
rule := NewSearchQueryInjectionRule() | ||
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.IsSearchRelated: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
"ta2": { | ||
Id: "ta2", | ||
Title: "Caller Technical Asset", | ||
OutOfScope: true, | ||
}, | ||
}, | ||
IncomingTechnicalCommunicationLinksMappedByTargetId: map[string][]*types.CommunicationLink{ | ||
"ta1": { | ||
{ | ||
SourceId: "ta2", | ||
Protocol: types.HTTP, | ||
}, | ||
}, | ||
}, | ||
}) | ||
|
||
assert.Nil(t, err) | ||
assert.Empty(t, risks) | ||
} | ||
|
||
func TestSearchQueryInjectionRuleGenerateRisksNoHTTPOrBinaryCommunicationNoRisksCreated(t *testing.T) { | ||
rule := NewSearchQueryInjectionRule() | ||
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.IsSearchRelated: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
"ta2": { | ||
Id: "ta2", | ||
Title: "Caller Technical Asset", | ||
OutOfScope: false, | ||
}, | ||
}, | ||
IncomingTechnicalCommunicationLinksMappedByTargetId: map[string][]*types.CommunicationLink{ | ||
"ta1": { | ||
{ | ||
SourceId: "ta2", | ||
Protocol: types.JDBC, | ||
}, | ||
}, | ||
}, | ||
}) | ||
|
||
assert.Nil(t, err) | ||
assert.Empty(t, risks) | ||
} | ||
|
||
type SearchQueryInjectionRuleTest struct { | ||
confidentiality types.Confidentiality | ||
integrity types.Criticality | ||
protocol types.Protocol | ||
usage types.Usage | ||
|
||
expectedImpact types.RiskExploitationImpact | ||
expectedLikelihood types.RiskExploitationLikelihood | ||
} | ||
|
||
func TestSearchQueryInjectionRuleGenerateRisksRiskCreated(t *testing.T) { | ||
testCases := map[string]SearchQueryInjectionRuleTest{ | ||
"medium impact": { | ||
confidentiality: types.Confidential, | ||
integrity: types.Critical, | ||
protocol: types.HTTP, | ||
usage: types.Business, | ||
expectedImpact: types.MediumImpact, | ||
expectedLikelihood: types.VeryLikely, | ||
}, | ||
"strictly confidential medium impact": { | ||
confidentiality: types.StrictlyConfidential, | ||
integrity: types.Critical, | ||
protocol: types.HTTP, | ||
usage: types.Business, | ||
expectedImpact: types.HighImpact, | ||
expectedLikelihood: types.VeryLikely, | ||
}, | ||
"mission critical integrity medium impact": { | ||
confidentiality: types.Confidential, | ||
integrity: types.Critical, | ||
protocol: types.HTTP, | ||
expectedImpact: types.MediumImpact, | ||
expectedLikelihood: types.VeryLikely, | ||
}, | ||
"low impact": { | ||
confidentiality: types.Internal, | ||
integrity: types.Operational, | ||
protocol: types.HTTP, | ||
usage: types.Business, | ||
expectedImpact: types.LowImpact, | ||
expectedLikelihood: types.VeryLikely, | ||
}, | ||
"HTTPS protocol": { | ||
confidentiality: types.Confidential, | ||
integrity: types.Critical, | ||
protocol: types.HTTPS, | ||
usage: types.Business, | ||
expectedImpact: types.MediumImpact, | ||
expectedLikelihood: types.VeryLikely, | ||
}, | ||
"Binary protocol": { | ||
confidentiality: types.Confidential, | ||
integrity: types.Critical, | ||
protocol: types.BINARY, | ||
usage: types.Business, | ||
expectedImpact: types.MediumImpact, | ||
expectedLikelihood: types.VeryLikely, | ||
}, | ||
"Binary encrypted protocol": { | ||
confidentiality: types.Confidential, | ||
integrity: types.Critical, | ||
protocol: types.BinaryEncrypted, | ||
usage: types.Business, | ||
expectedImpact: types.MediumImpact, | ||
expectedLikelihood: types.VeryLikely, | ||
}, | ||
"devops usage": { | ||
confidentiality: types.Confidential, | ||
integrity: types.Critical, | ||
protocol: types.BinaryEncrypted, | ||
usage: types.DevOps, | ||
expectedImpact: types.MediumImpact, | ||
expectedLikelihood: types.VeryLikely, | ||
}, | ||
} | ||
|
||
for name, testCase := range testCases { | ||
t.Run(name, func(t *testing.T) { | ||
rule := NewSearchQueryInjectionRule() | ||
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.IsSearchRelated: true, | ||
}, | ||
}, | ||
}, | ||
Confidentiality: testCase.confidentiality, | ||
Integrity: testCase.integrity, | ||
}, | ||
"ta2": { | ||
Id: "ta2", | ||
Title: "Caller Technical Asset", | ||
OutOfScope: false, | ||
}, | ||
}, | ||
IncomingTechnicalCommunicationLinksMappedByTargetId: map[string][]*types.CommunicationLink{ | ||
"ta1": { | ||
{ | ||
Title: "Call to ta1", | ||
SourceId: "ta2", | ||
Protocol: testCase.protocol, | ||
Usage: testCase.usage, | ||
}, | ||
}, | ||
}, | ||
}) | ||
|
||
assert.Nil(t, err) | ||
assert.Len(t, risks, 1) | ||
assert.Equal(t, testCase.expectedImpact, risks[0].ExploitationImpact) | ||
|
||
expTitle := "<b>Search Query Injection</b> risk at <b>Caller Technical Asset</b> against search engine server <b>Test Technical Asset</b> via <b>Call to ta1</b>" | ||
assert.Equal(t, expTitle, risks[0].Title) | ||
}) | ||
} | ||
} |