From 5b3bac61540c6892e20530f1839c3b2b6907afb6 Mon Sep 17 00:00:00 2001 From: Chris Yoo Date: Mon, 10 Feb 2025 17:03:41 +1100 Subject: [PATCH 1/5] add options to attack surface --- examples/nullify.yaml | 4 ++++ pkg/merger/merger_test.go | 20 ++++++++++++++------ pkg/models/attack_surface.go | 4 ++++ tests/integration_test.go | 4 ++++ tests/nullify.yaml | 4 ++++ 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/examples/nullify.yaml b/examples/nullify.yaml index 51ae6ef..a654fcd 100644 --- a/examples/nullify.yaml +++ b/examples/nullify.yaml @@ -115,3 +115,7 @@ attack_surface: enable_dns_enumeration: false domain_names: [172.36.255.7,example.com] ignore_domain_names: [] + path_prefixes: [/vuln] + ignore_methods: [POST,DELETE] + ignore_ports: [8080] + schemes: ["http","https"] diff --git a/pkg/merger/merger_test.go b/pkg/merger/merger_test.go index f7cc0e8..4c413a3 100644 --- a/pkg/merger/merger_test.go +++ b/pkg/merger/merger_test.go @@ -338,10 +338,14 @@ func TestMergeConfigFiles(t *testing.T) { name: "only global config for attack surface monitoring", globalConfig: &models.Configuration{ AttackSurface: &models.AttackSurface{ - Enable: true, + Enable: true, EnableDNSEnumeration: true, - DomainNames: []string{"example.com"}, - IgnoreDomainNames: []string{"example2.com"}, + DomainNames: []string{"example.com"}, + IgnoreDomainNames: []string{"example2.com"}, + PathPrefixes: []string{"/vuln"}, + IgnoreMethods: []string{"POST", "DELETE"}, + IgnorePorts: []int{8080}, + Schemes: []string{"http", "https"}, }, }, repoConfig: nil, @@ -351,10 +355,14 @@ func TestMergeConfigFiles(t *testing.T) { SeverityThreshold: parser.DefaultSeverityThreshold, PriorityThreshold: parser.DefaultPriorityThreshold, AttackSurface: &models.AttackSurface{ - Enable: true, + Enable: true, EnableDNSEnumeration: true, - DomainNames: []string{"example.com"}, - IgnoreDomainNames: []string{"example2.com"}, + DomainNames: []string{"example.com"}, + IgnoreDomainNames: []string{"example2.com"}, + PathPrefixes: []string{"/vuln"}, + IgnoreMethods: []string{"POST", "DELETE"}, + IgnorePorts: []int{8080}, + Schemes: []string{"http", "https"}, }, }, }, diff --git a/pkg/models/attack_surface.go b/pkg/models/attack_surface.go index d55b2b5..76f360f 100644 --- a/pkg/models/attack_surface.go +++ b/pkg/models/attack_surface.go @@ -6,4 +6,8 @@ type AttackSurface struct { EnableDNSEnumeration bool `yaml:"enable_dns_enumeration"` DomainNames []string `yaml:"domain_names,omitempty"` IgnoreDomainNames []string `yaml:"ignore_domain_names,omitempty"` + PathPrefixes []string `yaml:"path_prefixes,omitempty"` + IgnoreMethods []string `yaml:"ignore_methods,omitempty"` + IgnorePorts []int `yaml:"ignore_ports,omitempty"` + Schemes []string `yaml:"schemes"` } diff --git a/tests/integration_test.go b/tests/integration_test.go index 437037b..1c29833 100644 --- a/tests/integration_test.go +++ b/tests/integration_test.go @@ -158,6 +158,10 @@ func TestIntegration(t *testing.T) { EnableDNSEnumeration: true, DomainNames: []string{"172.36.255.7", "example.com"}, IgnoreDomainNames: []string{"jira.example.com"}, + PathPrefixes: []string{"/vuln"}, + IgnoreMethods: []string{"POST", "DELETE"}, + IgnorePorts: []int{8080}, + Schemes: []string{"http", "https"}, }, } diff --git a/tests/nullify.yaml b/tests/nullify.yaml index 8f5c1e4..5bd4f0f 100644 --- a/tests/nullify.yaml +++ b/tests/nullify.yaml @@ -99,3 +99,7 @@ attack_surface: enable_dns_enumeration: true domain_names: [172.36.255.7,example.com] ignore_domain_names: [jira.example.com] + path_prefixes: [/vuln] + ignore_methods: [POST,DELETE] + ignore_ports: [8080] + schemes: ["http","https"] \ No newline at end of file From e3d4935118e8f03d5c682260edbde6d75d66313b Mon Sep 17 00:00:00 2001 From: Chris Yoo Date: Tue, 11 Feb 2025 10:23:45 +1100 Subject: [PATCH 2/5] more flexible include_only and ignore rules --- examples/nullify.yaml | 48 +++++++++++++++++++---- pkg/merger/merger_test.go | 76 ++++++++++++++++++++++++++++++------ pkg/models/attack_surface.go | 37 ++++++++++++++---- tests/integration_test.go | 38 +++++++++++++++--- tests/nullify.yaml | 23 ++++++++--- 5 files changed, 182 insertions(+), 40 deletions(-) diff --git a/examples/nullify.yaml b/examples/nullify.yaml index a654fcd..f51bb14 100644 --- a/examples/nullify.yaml +++ b/examples/nullify.yaml @@ -62,7 +62,28 @@ code: - config-file-parser - dast-action - cli - - rule_ids: [ python-sql-injection ] + - rule_ids: [ python-sqlAttackSurface: &models.AttackSurface{ + Enable: true, + EnableDNSEnumeration: true, + DomainNames: []string{"172.36.255.7", "example.com"}, + PathPrefixes: []string{"/vuln"}, + Ignore: []models.AttackSurfaceIgnore{ + { + HTTPMethods: []string{"DELETE"}, + }, + { + HTTPMethods: []string{"jira.example.com"}, + }, + { + DomainNames: []string{"*.testing.example.com"}, + Ports: []int{8080, 8088, 9999}, + }, + { + DomainNames: []string{"dev.*", "staging.*"}, + HTTPMethods: []string{"POST", "PUT"}, + }, + }, + },-injection ] reason: This code won't be going live until next year but we should fix it before then expiry: "2021-12-31" dependencies: @@ -112,10 +133,21 @@ integrations: name: John Smith attack_surface: enable: true - enable_dns_enumeration: false - domain_names: [172.36.255.7,example.com] - ignore_domain_names: [] - path_prefixes: [/vuln] - ignore_methods: [POST,DELETE] - ignore_ports: [8080] - schemes: ["http","https"] + enable_dns_enumeration: true + ip_addresses: [10.11.12.13, 100.110.120.0/24, 10.0.0.1-254] + domain_names: [example.com, prod.hosting.com] + include_only: + - domain_names: [live.prod.hosting.com] + http: + paths: [/main, /api/**/create] + ignore: + - http: + methods: [DELETE] + - domain_names: [jira.example.com, "*.testing.example.com"] + - ip_addresses: [100.110.120.130] + transport_protocols: [tcp] + ports: [22, 8080, 9990-9999] + - domain_names: ["dev.*", "staging.*"] + http: + paths: [/auth] + methods: [POST] diff --git a/pkg/merger/merger_test.go b/pkg/merger/merger_test.go index 4c413a3..4832808 100644 --- a/pkg/merger/merger_test.go +++ b/pkg/merger/merger_test.go @@ -340,12 +340,38 @@ func TestMergeConfigFiles(t *testing.T) { AttackSurface: &models.AttackSurface{ Enable: true, EnableDNSEnumeration: true, - DomainNames: []string{"example.com"}, - IgnoreDomainNames: []string{"example2.com"}, - PathPrefixes: []string{"/vuln"}, - IgnoreMethods: []string{"POST", "DELETE"}, - IgnorePorts: []int{8080}, - Schemes: []string{"http", "https"}, + IPAddresses: []string{"10.11.12.13", "100.110.120.0/24", "10.0.0.1-254"}, + DomainNames: []string{"example.com", "prod.hosting.com"}, + IncludeOnly: []models.AttackSurfaceIncludeOnly{ + { + DomainNames: []string{"live.prod.hosting.com"}, + HTTP: &models.HTTPAttackSurfaceIncludeOnly{ + Paths: []string{"/main", "/api/**/create"}, + }, + }, + }, + Ignore: []models.AttackSurfaceIgnore{ + { + HTTP: &models.HTTPAttackSurfaceIgnore{ + Methods: []string{"DELETE"}, + }, + }, + { + DomainNames: []string{"jira.example.com", "*.testing.example.com"}, + }, + { + IPAddresses: []string{"100.110.120.130"}, + TransportProtocols: []string{"tcp"}, + Ports: []string{"22", "8080", "9990-9999"}, + }, + { + DomainNames: []string{"dev.*", "staging.*"}, + HTTP: &models.HTTPAttackSurfaceIgnore{ + Paths: []string{"/auth"}, + Methods: []string{"POST"}, + }, + }, + }, }, }, repoConfig: nil, @@ -357,12 +383,38 @@ func TestMergeConfigFiles(t *testing.T) { AttackSurface: &models.AttackSurface{ Enable: true, EnableDNSEnumeration: true, - DomainNames: []string{"example.com"}, - IgnoreDomainNames: []string{"example2.com"}, - PathPrefixes: []string{"/vuln"}, - IgnoreMethods: []string{"POST", "DELETE"}, - IgnorePorts: []int{8080}, - Schemes: []string{"http", "https"}, + IPAddresses: []string{"10.11.12.13", "100.110.120.0/24", "10.0.0.1-254"}, + DomainNames: []string{"example.com", "prod.hosting.com"}, + IncludeOnly: []models.AttackSurfaceIncludeOnly{ + { + DomainNames: []string{"live.prod.hosting.com"}, + HTTP: &models.HTTPAttackSurfaceIncludeOnly{ + Paths: []string{"/main", "/api/**/create"}, + }, + }, + }, + Ignore: []models.AttackSurfaceIgnore{ + { + HTTP: &models.HTTPAttackSurfaceIgnore{ + Methods: []string{"DELETE"}, + }, + }, + { + DomainNames: []string{"jira.example.com", "*.testing.example.com"}, + }, + { + IPAddresses: []string{"100.110.120.130"}, + TransportProtocols: []string{"tcp"}, + Ports: []string{"22", "8080", "9990-9999"}, + }, + { + DomainNames: []string{"dev.*", "staging.*"}, + HTTP: &models.HTTPAttackSurfaceIgnore{ + Paths: []string{"/auth"}, + Methods: []string{"POST"}, + }, + }, + }, }, }, }, diff --git a/pkg/models/attack_surface.go b/pkg/models/attack_surface.go index 76f360f..19d228d 100644 --- a/pkg/models/attack_surface.go +++ b/pkg/models/attack_surface.go @@ -2,12 +2,33 @@ package models type AttackSurface struct { // global only - Enable bool `yaml:"enable"` - EnableDNSEnumeration bool `yaml:"enable_dns_enumeration"` - DomainNames []string `yaml:"domain_names,omitempty"` - IgnoreDomainNames []string `yaml:"ignore_domain_names,omitempty"` - PathPrefixes []string `yaml:"path_prefixes,omitempty"` - IgnoreMethods []string `yaml:"ignore_methods,omitempty"` - IgnorePorts []int `yaml:"ignore_ports,omitempty"` - Schemes []string `yaml:"schemes"` + Enable bool `yaml:"enable"` + EnableDNSEnumeration bool `yaml:"enable_dns_enumeration"` + IPAddresses []string `yaml:"ip_addresses,omitempty"` + DomainNames []string `yaml:"domain_names,omitempty"` + IncludeOnly []AttackSurfaceIncludeOnly `yaml:"include_only,omitempty"` + Ignore []AttackSurfaceIgnore `yaml:"ignore,omitempty"` +} + +type AttackSurfaceIncludeOnly struct { + DomainNames []string `yaml:"domain_names,omitempty"` + HTTP *HTTPAttackSurfaceIncludeOnly `yaml:"http,omitempty"` +} + +type HTTPAttackSurfaceIncludeOnly struct { + Paths []string `yaml:"paths,omitempty"` +} + +type AttackSurfaceIgnore struct { + // empty fields are equivalent to * + IPAddresses []string `yaml:"ip_addresses,omitempty"` + DomainNames []string `yaml:"domain_names,omitempty"` + TransportProtocols []string `yaml:"transport_protocols,omitempty"` + Ports []string `yaml:"ports,omitempty"` + HTTP *HTTPAttackSurfaceIgnore `yaml:"http,omitempty"` +} + +type HTTPAttackSurfaceIgnore struct { + Methods []string `yaml:"methods,omitempty"` + Paths []string `yaml:"paths,omitempty"` } diff --git a/tests/integration_test.go b/tests/integration_test.go index 1c29833..7191fee 100644 --- a/tests/integration_test.go +++ b/tests/integration_test.go @@ -156,12 +156,38 @@ func TestIntegration(t *testing.T) { AttackSurface: &models.AttackSurface{ Enable: true, EnableDNSEnumeration: true, - DomainNames: []string{"172.36.255.7", "example.com"}, - IgnoreDomainNames: []string{"jira.example.com"}, - PathPrefixes: []string{"/vuln"}, - IgnoreMethods: []string{"POST", "DELETE"}, - IgnorePorts: []int{8080}, - Schemes: []string{"http", "https"}, + IPAddresses: []string{"10.11.12.13", "100.110.120.0/24", "10.0.0.1-254"}, + DomainNames: []string{"example.com", "prod.hosting.com"}, + IncludeOnly: []models.AttackSurfaceIncludeOnly{ + { + DomainNames: []string{"live.prod.hosting.com"}, + HTTP: &models.HTTPAttackSurfaceIncludeOnly{ + Paths: []string{"/main", "/api/**/create"}, + }, + }, + }, + Ignore: []models.AttackSurfaceIgnore{ + { + HTTP: &models.HTTPAttackSurfaceIgnore{ + Methods: []string{"DELETE"}, + }, + }, + { + DomainNames: []string{"jira.example.com", "*.testing.example.com"}, + }, + { + IPAddresses: []string{"100.110.120.130"}, + TransportProtocols: []string{"tcp"}, + Ports: []string{"22", "8080", "9990-9999"}, + }, + { + DomainNames: []string{"dev.*", "staging.*"}, + HTTP: &models.HTTPAttackSurfaceIgnore{ + Paths: []string{"/auth"}, + Methods: []string{"POST"}, + }, + }, + }, }, } diff --git a/tests/nullify.yaml b/tests/nullify.yaml index 5bd4f0f..e8efacf 100644 --- a/tests/nullify.yaml +++ b/tests/nullify.yaml @@ -97,9 +97,20 @@ integrations: attack_surface: enable: true enable_dns_enumeration: true - domain_names: [172.36.255.7,example.com] - ignore_domain_names: [jira.example.com] - path_prefixes: [/vuln] - ignore_methods: [POST,DELETE] - ignore_ports: [8080] - schemes: ["http","https"] \ No newline at end of file + ip_addresses: [10.11.12.13, 100.110.120.0/24, 10.0.0.1-254] + domain_names: [example.com, prod.hosting.com] + include_only: + - domain_names: [live.prod.hosting.com] + http: + paths: [/main, /api/**/create] + ignore: + - http: + methods: [DELETE] + - domain_names: [jira.example.com, "*.testing.example.com"] + - ip_addresses: [100.110.120.130] + transport_protocols: [tcp] + ports: [22, 8080, 9990-9999] + - domain_names: ["dev.*", "staging.*"] + http: + paths: [/auth] + methods: [POST] From 7b03329196e17a6f70657d4d36f2e2de864d4f1e Mon Sep 17 00:00:00 2001 From: Chris Yoo Date: Tue, 11 Feb 2025 10:26:58 +1100 Subject: [PATCH 3/5] revert subnets for ip address --- examples/nullify.yaml | 2 +- pkg/merger/merger_test.go | 4 ++-- tests/integration_test.go | 2 +- tests/nullify.yaml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/nullify.yaml b/examples/nullify.yaml index f51bb14..6f16567 100644 --- a/examples/nullify.yaml +++ b/examples/nullify.yaml @@ -134,7 +134,7 @@ integrations: attack_surface: enable: true enable_dns_enumeration: true - ip_addresses: [10.11.12.13, 100.110.120.0/24, 10.0.0.1-254] + ip_addresses: [10.11.12.13, 10.0.0.1-254] domain_names: [example.com, prod.hosting.com] include_only: - domain_names: [live.prod.hosting.com] diff --git a/pkg/merger/merger_test.go b/pkg/merger/merger_test.go index 4832808..cecadaf 100644 --- a/pkg/merger/merger_test.go +++ b/pkg/merger/merger_test.go @@ -340,7 +340,7 @@ func TestMergeConfigFiles(t *testing.T) { AttackSurface: &models.AttackSurface{ Enable: true, EnableDNSEnumeration: true, - IPAddresses: []string{"10.11.12.13", "100.110.120.0/24", "10.0.0.1-254"}, + IPAddresses: []string{"10.11.12.13", "10.0.0.1-254"}, DomainNames: []string{"example.com", "prod.hosting.com"}, IncludeOnly: []models.AttackSurfaceIncludeOnly{ { @@ -383,7 +383,7 @@ func TestMergeConfigFiles(t *testing.T) { AttackSurface: &models.AttackSurface{ Enable: true, EnableDNSEnumeration: true, - IPAddresses: []string{"10.11.12.13", "100.110.120.0/24", "10.0.0.1-254"}, + IPAddresses: []string{"10.11.12.13", "10.0.0.1-254"}, DomainNames: []string{"example.com", "prod.hosting.com"}, IncludeOnly: []models.AttackSurfaceIncludeOnly{ { diff --git a/tests/integration_test.go b/tests/integration_test.go index 7191fee..004243c 100644 --- a/tests/integration_test.go +++ b/tests/integration_test.go @@ -156,7 +156,7 @@ func TestIntegration(t *testing.T) { AttackSurface: &models.AttackSurface{ Enable: true, EnableDNSEnumeration: true, - IPAddresses: []string{"10.11.12.13", "100.110.120.0/24", "10.0.0.1-254"}, + IPAddresses: []string{"10.11.12.13", "10.0.0.1-254"}, DomainNames: []string{"example.com", "prod.hosting.com"}, IncludeOnly: []models.AttackSurfaceIncludeOnly{ { diff --git a/tests/nullify.yaml b/tests/nullify.yaml index e8efacf..979f7d3 100644 --- a/tests/nullify.yaml +++ b/tests/nullify.yaml @@ -97,7 +97,7 @@ integrations: attack_surface: enable: true enable_dns_enumeration: true - ip_addresses: [10.11.12.13, 100.110.120.0/24, 10.0.0.1-254] + ip_addresses: [10.11.12.13, 10.0.0.1-254] domain_names: [example.com, prod.hosting.com] include_only: - domain_names: [live.prod.hosting.com] From 364cd9bcfd98840728ced1d9a713eece1f41cc7d Mon Sep 17 00:00:00 2001 From: Chris Yoo Date: Tue, 11 Feb 2025 10:30:14 +1100 Subject: [PATCH 4/5] revert accidental copypaste --- examples/nullify.yaml | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/examples/nullify.yaml b/examples/nullify.yaml index 6f16567..c96032d 100644 --- a/examples/nullify.yaml +++ b/examples/nullify.yaml @@ -62,28 +62,7 @@ code: - config-file-parser - dast-action - cli - - rule_ids: [ python-sqlAttackSurface: &models.AttackSurface{ - Enable: true, - EnableDNSEnumeration: true, - DomainNames: []string{"172.36.255.7", "example.com"}, - PathPrefixes: []string{"/vuln"}, - Ignore: []models.AttackSurfaceIgnore{ - { - HTTPMethods: []string{"DELETE"}, - }, - { - HTTPMethods: []string{"jira.example.com"}, - }, - { - DomainNames: []string{"*.testing.example.com"}, - Ports: []int{8080, 8088, 9999}, - }, - { - DomainNames: []string{"dev.*", "staging.*"}, - HTTPMethods: []string{"POST", "PUT"}, - }, - }, - },-injection ] + - rule_ids: [ python-sql-injection ] reason: This code won't be going live until next year but we should fix it before then expiry: "2021-12-31" dependencies: @@ -150,4 +129,4 @@ attack_surface: - domain_names: ["dev.*", "staging.*"] http: paths: [/auth] - methods: [POST] + methods: [POST] \ No newline at end of file From e59e5f08ede26f1bbdabcf2465e305c73f20841e Mon Sep 17 00:00:00 2001 From: Chris Yoo Date: Tue, 11 Feb 2025 10:31:06 +1100 Subject: [PATCH 5/5] add newline --- examples/nullify.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/nullify.yaml b/examples/nullify.yaml index c96032d..0edae6b 100644 --- a/examples/nullify.yaml +++ b/examples/nullify.yaml @@ -129,4 +129,4 @@ attack_surface: - domain_names: ["dev.*", "staging.*"] http: paths: [/auth] - methods: [POST] \ No newline at end of file + methods: [POST]