diff --git a/avd_docs/nifcloud/dns/AVD-NIF-0007/docs.md b/avd_docs/nifcloud/dns/AVD-NIF-0007/docs.md index 70cde121..8977670c 100644 --- a/avd_docs/nifcloud/dns/AVD-NIF-0007/docs.md +++ b/avd_docs/nifcloud/dns/AVD-NIF-0007/docs.md @@ -1,10 +1,11 @@ +Removing verified record of TXT auth the risk that -Removing verified record of TXT auth the risk that If the authentication record remains, anyone can register the zone + ### Impact -Risk of DNS records be used by others + {{ remediationActions }} diff --git a/avd_docs/nifcloud/network/AVD-NIF-0016/docs.md b/avd_docs/nifcloud/network/AVD-NIF-0016/docs.md index feea9c8f..76bc88fb 100644 --- a/avd_docs/nifcloud/network/AVD-NIF-0016/docs.md +++ b/avd_docs/nifcloud/network/AVD-NIF-0016/docs.md @@ -1,8 +1,9 @@ Need to add a security group to your router. + ### Impact -A security group controls the traffic that is allowed to reach and leave the resources that it is associated with. + {{ remediationActions }} diff --git a/avd_docs/nifcloud/network/AVD-NIF-0017/docs.md b/avd_docs/nifcloud/network/AVD-NIF-0017/docs.md index 26a9f074..e3c3e949 100644 --- a/avd_docs/nifcloud/network/AVD-NIF-0017/docs.md +++ b/avd_docs/nifcloud/network/AVD-NIF-0017/docs.md @@ -1,8 +1,9 @@ When handling sensitive data between servers, please consider using a private LAN to isolate the private side network from the shared network. + ### Impact -The common private network is shared with other users + {{ remediationActions }} diff --git a/avd_docs/nifcloud/network/AVD-NIF-0018/docs.md b/avd_docs/nifcloud/network/AVD-NIF-0018/docs.md index fb879828..eeef83fb 100644 --- a/avd_docs/nifcloud/network/AVD-NIF-0018/docs.md +++ b/avd_docs/nifcloud/network/AVD-NIF-0018/docs.md @@ -1,8 +1,9 @@ Need to add a security group to your vpnGateway. + ### Impact -A security group controls the traffic that is allowed to reach and leave the resources that it is associated with. + {{ remediationActions }} diff --git a/avd_docs/nifcloud/network/AVD-NIF-0019/docs.md b/avd_docs/nifcloud/network/AVD-NIF-0019/docs.md index 26a9f074..e3c3e949 100644 --- a/avd_docs/nifcloud/network/AVD-NIF-0019/docs.md +++ b/avd_docs/nifcloud/network/AVD-NIF-0019/docs.md @@ -1,8 +1,9 @@ When handling sensitive data between servers, please consider using a private LAN to isolate the private side network from the shared network. + ### Impact -The common private network is shared with other users + {{ remediationActions }} diff --git a/avd_docs/nifcloud/network/AVD-NIF-0020/docs.md b/avd_docs/nifcloud/network/AVD-NIF-0020/docs.md index 9587778e..2d26f94d 100644 --- a/avd_docs/nifcloud/network/AVD-NIF-0020/docs.md +++ b/avd_docs/nifcloud/network/AVD-NIF-0020/docs.md @@ -1,8 +1,9 @@ You should not use outdated/insecure TLS versions for encryption. You should be using TLS v1.2+. + ### Impact -The SSL policy is outdated and has known vulnerabilities + {{ remediationActions }} diff --git a/avd_docs/nifcloud/network/AVD-NIF-0021/docs.md b/avd_docs/nifcloud/network/AVD-NIF-0021/docs.md index b5ec5a8b..5e71fa38 100644 --- a/avd_docs/nifcloud/network/AVD-NIF-0021/docs.md +++ b/avd_docs/nifcloud/network/AVD-NIF-0021/docs.md @@ -3,8 +3,9 @@ Plain HTTP is unencrypted and human-readable. This means that if a malicious act You should use HTTPS, which is HTTP over an encrypted (TLS) connection, meaning eavesdroppers cannot read your traffic. + ### Impact -Your traffic is not protected + {{ remediationActions }} diff --git a/avd_docs/nifcloud/sslcertificate/AVD-NIF-0006/docs.md b/avd_docs/nifcloud/sslcertificate/AVD-NIF-0006/docs.md index f450bb5d..52e333da 100644 --- a/avd_docs/nifcloud/sslcertificate/AVD-NIF-0006/docs.md +++ b/avd_docs/nifcloud/sslcertificate/AVD-NIF-0006/docs.md @@ -1,13 +1,15 @@ - Removing expired SSL/TLS certificates eliminates the risk that an invalid certificate will be -deployed accidentally to a resource such as NIFCLOUD Load Balancer(L4LB), which candamage the + +deployed accidentally to a resource such as NIFCLOUD Load Balancer(L4LB), which candamage the + credibility of the application/website behind the L4LB. As a best practice, it is + recommended to delete expired certificates. - + ### Impact -Risk of misconfiguration and damage to credibility + {{ remediationActions }} diff --git a/checks/cloud/nifcloud/dns/remove_verified_record.go b/checks/cloud/nifcloud/dns/remove_verified_record.go index 8731fb5e..dc101b98 100644 --- a/checks/cloud/nifcloud/dns/remove_verified_record.go +++ b/checks/cloud/nifcloud/dns/remove_verified_record.go @@ -28,7 +28,8 @@ If the authentication record remains, anyone can register the zone`, Links: []string{ "https://pfs.nifcloud.com/guide/dns/zone_new.htm", }, - Severity: severity.Critical, + Severity: severity.Critical, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, record := range s.Nifcloud.DNS.Records { diff --git a/checks/cloud/nifcloud/dns/remove_verified_record.rego b/checks/cloud/nifcloud/dns/remove_verified_record.rego new file mode 100644 index 00000000..5a8b37c3 --- /dev/null +++ b/checks/cloud/nifcloud/dns/remove_verified_record.rego @@ -0,0 +1,37 @@ +# METADATA +# title: Delete verified record +# description: | +# Removing verified record of TXT auth the risk that +# +# If the authentication record remains, anyone can register the zone +# scope: package +# schemas: +# - input: schema["cloud"] +# related_resources: +# - https://pfs.nifcloud.com/guide/dns/zone_new.htm +# custom: +# id: AVD-NIF-0007 +# avd_id: AVD-NIF-0007 +# provider: nifcloud +# service: dns +# severity: CRITICAL +# short_code: remove-verified-record +# recommended_action: Remove verified record +# input: +# selector: +# - type: cloud +# subtypes: +# - service: dns +# provider: nifcloud +package builtin.nifcloud.dns.nifcloud0007 + +import rego.v1 + +zone_registration_auth_txt := "nifty-dns-verify=" + +deny contains res if { + some record in input.nifcloud.dns.records + record.type.value == "TXT" + startswith(record.record.value, zone_registration_auth_txt) + res := result.new("Authentication TXT record exists.", record) +} diff --git a/checks/cloud/nifcloud/dns/remove_verified_record_test.go b/checks/cloud/nifcloud/dns/remove_verified_record_test.go deleted file mode 100644 index 0d089c85..00000000 --- a/checks/cloud/nifcloud/dns/remove_verified_record_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package dns - -import ( - "testing" - - "github.com/aquasecurity/trivy/pkg/iac/providers/nifcloud/dns" - "github.com/aquasecurity/trivy/pkg/iac/scan" - "github.com/aquasecurity/trivy/pkg/iac/state" - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - "github.com/stretchr/testify/assert" -) - -func TestCheckRemoveVerifiedRecord(t *testing.T) { - tests := []struct { - name string - input dns.DNS - expected bool - }{ - { - name: "No records", - input: dns.DNS{}, - expected: false, - }, - { - name: "Some record", - input: dns.DNS{ - Records: []dns.Record{ - { - Metadata: trivyTypes.NewTestMetadata(), - Type: trivyTypes.String("A", trivyTypes.NewTestMetadata()), - Record: trivyTypes.String("some", trivyTypes.NewTestMetadata()), - }, - }, - }, - expected: false, - }, - { - name: "Some TXT record", - input: dns.DNS{ - Records: []dns.Record{ - { - Metadata: trivyTypes.NewTestMetadata(), - Type: trivyTypes.String("TXT", trivyTypes.NewTestMetadata()), - Record: trivyTypes.String("some", trivyTypes.NewTestMetadata()), - }, - }, - }, - expected: false, - }, - - { - name: "Verify TXT record", - input: dns.DNS{ - Records: []dns.Record{ - { - Metadata: trivyTypes.NewTestMetadata(), - Type: trivyTypes.String("TXT", trivyTypes.NewTestMetadata()), - Record: trivyTypes.String(dns.ZoneRegistrationAuthTxt, trivyTypes.NewTestMetadata()), - }, - }, - }, - expected: true, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.Nifcloud.DNS = test.input - results := CheckRemoveVerifiedRecord.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckRemoveVerifiedRecord.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/checks/cloud/nifcloud/dns/remove_verified_record_test.rego b/checks/cloud/nifcloud/dns/remove_verified_record_test.rego new file mode 100644 index 00000000..9cc808b0 --- /dev/null +++ b/checks/cloud/nifcloud/dns/remove_verified_record_test.rego @@ -0,0 +1,38 @@ +package builtin.nifcloud.dns.nifcloud0007_test + +import rego.v1 + +import data.builtin.nifcloud.dns.nifcloud0007 as check +import data.lib.test + +test_allow_txt_record if { + inp := build_input({ + "type": {"value": "TXT"}, + "record": {"value": "test"}, + }) + + res := check.deny with input as inp + res == set() +} + +test_deny_verified_txt_record if { + inp := build_input({ + "type": {"value": "TXT"}, + "record": {"value": "nifty-dns-verify=test"}, + }) + + res := check.deny with input as inp + count(res) == 1 +} + +test_allow_verified_not_txt_record if { + inp := build_input({ + "type": {"value": "A"}, + "record": {"value": "nifty-dns-verify=test"}, + }) + + res := check.deny with input as inp + res == set() +} + +build_input(record) := {"nifcloud": {"dns": {"records": [record]}}} diff --git a/checks/cloud/nifcloud/network/add_security_group_to_router.go b/checks/cloud/nifcloud/network/add_security_group_to_router.go index 31c910d8..d21ced6a 100755 --- a/checks/cloud/nifcloud/network/add_security_group_to_router.go +++ b/checks/cloud/nifcloud/network/add_security_group_to_router.go @@ -28,7 +28,8 @@ var CheckAddSecurityGroupToRouter = rules.Register( Links: terraformAddSecurityGroupToRouterLinks, RemediationMarkdown: terraformAddSecurityGroupToRouterRemediationMarkdown, }, - Severity: severity.Critical, + Severity: severity.Critical, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, router := range s.Nifcloud.Network.Routers { diff --git a/checks/cloud/nifcloud/network/add_security_group_to_router.rego b/checks/cloud/nifcloud/network/add_security_group_to_router.rego new file mode 100644 index 00000000..0bf73643 --- /dev/null +++ b/checks/cloud/nifcloud/network/add_security_group_to_router.rego @@ -0,0 +1,37 @@ +# METADATA +# title: Missing security group for router. +# description: | +# Need to add a security group to your router. +# scope: package +# schemas: +# - input: schema["cloud"] +# related_resources: +# - https://pfs.nifcloud.com/help/router/change.htm +# custom: +# id: AVD-NIF-0016 +# avd_id: AVD-NIF-0016 +# provider: nifcloud +# service: network +# severity: CRITICAL +# short_code: add-security-group-to-router +# recommended_action: Add security group for all routers +# input: +# selector: +# - type: cloud +# subtypes: +# - service: network +# provider: nifcloud +# terraform: +# links: +# - https://registry.terraform.io/providers/nifcloud/nifcloud/latest/docs/resources/router#security_group +# good_examples: checks/cloud/nifcloud/network/add_security_group_to_router.tf.go +# bad_examples: checks/cloud/nifcloud/network/add_security_group_to_router.tf.go +package builtin.nifcloud.network.nifcloud0016 + +import rego.v1 + +deny contains res if { + some router in input.nifcloud.network.routers + router.securitygroup.value == "" + res := result.new("Router does not have a securiy group.", router.securitygroup) +} diff --git a/checks/cloud/nifcloud/network/add_security_group_to_router_test.go b/checks/cloud/nifcloud/network/add_security_group_to_router_test.go deleted file mode 100644 index 00c12143..00000000 --- a/checks/cloud/nifcloud/network/add_security_group_to_router_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package network - -import ( - "testing" - - "github.com/aquasecurity/trivy/pkg/iac/providers/nifcloud/network" - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - - "github.com/aquasecurity/trivy/pkg/iac/state" - - "github.com/aquasecurity/trivy/pkg/iac/scan" - - "github.com/stretchr/testify/assert" -) - -func TestCheckAddSecurityGroupToRouter(t *testing.T) { - tests := []struct { - name string - input network.Network - expected bool - }{ - { - name: "NIFCLOUD router with no security group provided", - input: network.Network{ - Routers: []network.Router{ - { - Metadata: trivyTypes.NewTestMetadata(), - SecurityGroup: trivyTypes.String("", trivyTypes.NewTestMetadata()), - }, - }, - }, - expected: true, - }, - { - name: "NIFCLOUD router with security group", - input: network.Network{ - Routers: []network.Router{ - { - Metadata: trivyTypes.NewTestMetadata(), - SecurityGroup: trivyTypes.String("some security group", trivyTypes.NewTestMetadata()), - }, - }, - }, - expected: false, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.Nifcloud.Network = test.input - results := CheckAddSecurityGroupToRouter.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckAddSecurityGroupToRouter.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/checks/cloud/nifcloud/network/add_security_group_to_router_test.rego b/checks/cloud/nifcloud/network/add_security_group_to_router_test.rego new file mode 100644 index 00000000..7cf81690 --- /dev/null +++ b/checks/cloud/nifcloud/network/add_security_group_to_router_test.rego @@ -0,0 +1,20 @@ +package builtin.nifcloud.network.nifcloud0016_test + +import rego.v1 + +import data.builtin.nifcloud.network.nifcloud0016 as check +import data.lib.test + +test_allow_router_with_sg if { + inp := {"nifcloud": {"network": {"routers": [{"securitygroup": {"value": "some-group"}}]}}} + + res := check.deny with input as inp + res == set() +} + +test_deny_router_without_sg if { + inp := {"nifcloud": {"network": {"routers": [{"securitygroup": {"value": ""}}]}}} + + res := check.deny with input as inp + count(res) == 1 +} diff --git a/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.go b/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.go index d97812c8..6c48c2d0 100755 --- a/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.go +++ b/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.go @@ -28,7 +28,8 @@ var CheckAddSecurityGroupToVpnGateway = rules.Register( Links: terraformAddSecurityGroupToVpnGatewayLinks, RemediationMarkdown: terraformAddSecurityGroupToVpnGatewayRemediationMarkdown, }, - Severity: severity.Critical, + Severity: severity.Critical, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, vpnGateway := range s.Nifcloud.Network.VpnGateways { diff --git a/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.rego b/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.rego new file mode 100644 index 00000000..376d9dfb --- /dev/null +++ b/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.rego @@ -0,0 +1,37 @@ +# METADATA +# title: Missing security group for vpnGateway. +# description: | +# Need to add a security group to your vpnGateway. +# scope: package +# schemas: +# - input: schema["cloud"] +# related_resources: +# - https://pfs.nifcloud.com/help/vpngw/change.htm +# custom: +# id: AVD-NIF-0018 +# avd_id: AVD-NIF-0018 +# provider: nifcloud +# service: network +# severity: CRITICAL +# short_code: add-security-group-to-vpn-gateway +# recommended_action: Add security group for all vpnGateways +# input: +# selector: +# - type: cloud +# subtypes: +# - service: network +# provider: nifcloud +# terraform: +# links: +# - https://registry.terraform.io/providers/nifcloud/nifcloud/latest/docs/resources/vpn_gateway#security_group +# good_examples: checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.tf.go +# bad_examples: checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway.tf.go +package builtin.nifcloud.network.nifcloud0018 + +import rego.v1 + +deny contains res if { + some gateway in input.nifcloud.network.vpngateways + gateway.securitygroup.value == "" + res := result.new("VpnGateway does not have a securiy group.", gateway.securitygroup) +} diff --git a/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway_test.go b/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway_test.go deleted file mode 100644 index 5b905e5b..00000000 --- a/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package network - -import ( - "testing" - - "github.com/aquasecurity/trivy/pkg/iac/providers/nifcloud/network" - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - - "github.com/aquasecurity/trivy/pkg/iac/state" - - "github.com/aquasecurity/trivy/pkg/iac/scan" - - "github.com/stretchr/testify/assert" -) - -func TestCheckAddSecurityGroupToVpnGateway(t *testing.T) { - tests := []struct { - name string - input network.Network - expected bool - }{ - { - name: "NIFCLOUD vpnGateway with no security group provided", - input: network.Network{ - VpnGateways: []network.VpnGateway{ - { - Metadata: trivyTypes.NewTestMetadata(), - SecurityGroup: trivyTypes.String("", trivyTypes.NewTestMetadata()), - }, - }, - }, - expected: true, - }, - { - name: "NIFCLOUD vpnGateway with security group", - input: network.Network{ - VpnGateways: []network.VpnGateway{ - { - Metadata: trivyTypes.NewTestMetadata(), - SecurityGroup: trivyTypes.String("some security group", trivyTypes.NewTestMetadata()), - }, - }, - }, - expected: false, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.Nifcloud.Network = test.input - results := CheckAddSecurityGroupToVpnGateway.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckAddSecurityGroupToVpnGateway.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway_test.rego b/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway_test.rego new file mode 100644 index 00000000..cd8e7fe7 --- /dev/null +++ b/checks/cloud/nifcloud/network/add_security_group_to_vpn_gateway_test.rego @@ -0,0 +1,19 @@ +package builtin.nifcloud.network.nifcloud0018_test + +import rego.v1 + +import data.builtin.nifcloud.network.nifcloud0018 as check +import data.lib.test + +test_allow_gateway_with_sg if { + inp := {"nifcloud": {"network": {"vpngateways": [{"securitygroup": {"value": "some-group"}}]}}} + + res := check.deny with input as inp + res == set() +} + +test_deny_gateway_without_sg if { + inp := {"nifcloud": {"network": {"vpngateways": [{"securitygroup": {"value": ""}}]}}} + res := check.deny with input as inp + count(res) == 1 +} diff --git a/checks/cloud/nifcloud/network/http_not_used.go b/checks/cloud/nifcloud/network/http_not_used.go index 60c19533..7240370b 100755 --- a/checks/cloud/nifcloud/network/http_not_used.go +++ b/checks/cloud/nifcloud/network/http_not_used.go @@ -29,7 +29,8 @@ You should use HTTPS, which is HTTP over an encrypted (TLS) connection, meaning Links: terraformHttpNotUsedLinks, RemediationMarkdown: terraformHttpNotUsedRemediationMarkdown, }, - Severity: severity.Critical, + Severity: severity.Critical, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, lb := range s.Nifcloud.Network.LoadBalancers { diff --git a/checks/cloud/nifcloud/network/http_not_used.rego b/checks/cloud/nifcloud/network/http_not_used.rego new file mode 100644 index 00000000..c7e865c7 --- /dev/null +++ b/checks/cloud/nifcloud/network/http_not_used.rego @@ -0,0 +1,56 @@ +# METADATA +# title: Use of plain HTTP. +# description: | +# Plain HTTP is unencrypted and human-readable. This means that if a malicious actor was to eavesdrop on your connection, they would be able to see all of your data flowing back and forth. +# +# You should use HTTPS, which is HTTP over an encrypted (TLS) connection, meaning eavesdroppers cannot read your traffic. +# scope: package +# schemas: +# - input: schema["cloud"] +# related_resources: +# - https://www.cloudflare.com/en-gb/learning/ssl/why-is-http-not-secure/ +# custom: +# id: AVD-NIF-0021 +# avd_id: AVD-NIF-0021 +# provider: nifcloud +# service: network +# severity: CRITICAL +# short_code: http-not-used +# recommended_action: Switch to HTTPS to benefit from TLS security features +# input: +# selector: +# - type: cloud +# subtypes: +# - service: network +# provider: nifcloud +# terraform: +# links: +# - https://registry.terraform.io/providers/nifcloud/nifcloud/latest/docs/resources/elb#protocol +# - https://registry.terraform.io/providers/nifcloud/nifcloud/latest/docs/resources/load_balancer#load_balancer_port +# good_examples: checks/cloud/nifcloud/network/http_not_used.tf.go +# bad_examples: checks/cloud/nifcloud/network/http_not_used.tf.go +package builtin.nifcloud.network.nifcloud0021 + +import rego.v1 + +deny contains res if { + some lb in input.nifcloud.network.loadbalancers + some listener in lb.listeners + listener.protocol.value == "HTTP" + res := result.new("Listener for l4 load balancer does not use HTTPS.", listener.protocol) +} + +deny contains res if { + some elb in input.nifcloud.network.elasticloadbalancers + not is_private_lb(elb) + some listener in elb.listeners + listener.protocol.value == "HTTP" + res := result.new("Listener for multi load balancer does not use HTTPS.", listener.protocol) +} + +is_private_lb(lb) if { + some ni in lb.networkinterfaces + print(ni) + ni.networkid.value != "net-COMMON_GLOBAL" + ni.isvipnetwork.value == false +} diff --git a/checks/cloud/nifcloud/network/http_not_used_test.go b/checks/cloud/nifcloud/network/http_not_used_test.go deleted file mode 100644 index 04dc04a6..00000000 --- a/checks/cloud/nifcloud/network/http_not_used_test.go +++ /dev/null @@ -1,141 +0,0 @@ -package network - -import ( - "testing" - - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - - "github.com/aquasecurity/trivy/pkg/iac/state" - - "github.com/aquasecurity/trivy/pkg/iac/providers/nifcloud/network" - "github.com/aquasecurity/trivy/pkg/iac/scan" - - "github.com/stretchr/testify/assert" -) - -func TestCheckHttpNotUsed(t *testing.T) { - tests := []struct { - name string - input network.Network - expected bool - }{ - { - name: "Elastic Load balancer listener with HTTP protocol on global", - input: network.Network{ - ElasticLoadBalancers: []network.ElasticLoadBalancer{ - { - Metadata: trivyTypes.NewTestMetadata(), - NetworkInterfaces: []network.NetworkInterface{{ - Metadata: trivyTypes.NewTestMetadata(), - NetworkID: trivyTypes.String("net-COMMON_GLOBAL", trivyTypes.NewTestMetadata()), - IsVipNetwork: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), - }}, - Listeners: []network.ElasticLoadBalancerListener{ - { - Metadata: trivyTypes.NewTestMetadata(), - Protocol: trivyTypes.String("HTTP", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "Elastic Load balancer listener with HTTP protocol on internal", - input: network.Network{ - ElasticLoadBalancers: []network.ElasticLoadBalancer{ - { - Metadata: trivyTypes.NewTestMetadata(), - NetworkInterfaces: []network.NetworkInterface{{ - Metadata: trivyTypes.NewTestMetadata(), - NetworkID: trivyTypes.String("some-network", trivyTypes.NewTestMetadata()), - IsVipNetwork: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), - }}, - Listeners: []network.ElasticLoadBalancerListener{ - { - Metadata: trivyTypes.NewTestMetadata(), - Protocol: trivyTypes.String("HTTP", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: false, - }, - { - name: "Elastic Load balancer listener with HTTPS protocol on global", - input: network.Network{ - ElasticLoadBalancers: []network.ElasticLoadBalancer{ - { - Metadata: trivyTypes.NewTestMetadata(), - NetworkInterfaces: []network.NetworkInterface{{ - Metadata: trivyTypes.NewTestMetadata(), - NetworkID: trivyTypes.String("net-COMMON_GLOBAL", trivyTypes.NewTestMetadata()), - IsVipNetwork: trivyTypes.Bool(true, trivyTypes.NewTestMetadata()), - }}, - Listeners: []network.ElasticLoadBalancerListener{ - { - Metadata: trivyTypes.NewTestMetadata(), - Protocol: trivyTypes.String("HTTPS", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: false, - }, - { - name: "Load balancer listener with HTTP protocol", - input: network.Network{ - LoadBalancers: []network.LoadBalancer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Listeners: []network.LoadBalancerListener{ - { - Metadata: trivyTypes.NewTestMetadata(), - Protocol: trivyTypes.String("HTTP", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "Load balancer listener with HTTPS protocol", - input: network.Network{ - LoadBalancers: []network.LoadBalancer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Listeners: []network.LoadBalancerListener{ - { - Metadata: trivyTypes.NewTestMetadata(), - Protocol: trivyTypes.String("HTTPS", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: false, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.Nifcloud.Network = test.input - results := CheckHttpNotUsed.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckHttpNotUsed.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/checks/cloud/nifcloud/network/http_not_used_test.rego b/checks/cloud/nifcloud/network/http_not_used_test.rego new file mode 100644 index 00000000..cb232b50 --- /dev/null +++ b/checks/cloud/nifcloud/network/http_not_used_test.rego @@ -0,0 +1,53 @@ +package builtin.nifcloud.network.nifcloud0021_test + +import rego.v1 + +import data.builtin.nifcloud.network.nifcloud0021 as check +import data.lib.test + +test_deny_elastic_lb_with_http_protocol_on_global if { + inp := build_elb_input({ + "networkinterfaces": [{"networkid": {"value": "net-COMMON_GLOBAL", "isvipnetwork": {"value": true}}}, {"networkid": {"value": "some-network"}}], + "listeners": [{"protocol": {"value": "HTTP"}}], + }) + + res := check.deny with input as inp + count(res) == 1 +} + +test_allow_elastic_lb_with_http_protocol_on_internal if { + inp := build_elb_input({ + "networkinterfaces": [{"networkid": {"value": "some-network"}, "isvipnetwork": {"value": false}}], + "listeners": [{"protocol": {"value": "HTTP"}}], + }) + + res := check.deny with input as inp + res == set() +} + +test_allow_elastic_lb_with_https_protocol_on_global if { + inp := build_elb_input({ + "networkinterfaces": [{"networkid": {"value": "net-COMMON_GLOBAL"}, "isvipnetwork": {"value": true}}], + "listeners": [{"protocol": {"value": "HTTPS"}}], + }) + + res := check.deny with input as inp + print(res) + res == set() +} + +test_deny_lb_with_http_protocol if { + inp := {"nifcloud": {"network": {"loadbalancers": [{"listeners": [{"protocol": {"value": "HTTP"}}]}]}}} + + res := check.deny with input as inp + count(res) == 1 +} + +test_allow_lb_with_https_protocol if { + inp := {"nifcloud": {"network": {"loadbalancers": [{"listeners": [{"protocol": {"value": "HTTPS"}}]}]}}} + + res := check.deny with input as inp + res == set() +} + +build_elb_input(elb) := {"nifcloud": {"network": {"elasticloadbalancers": [elb]}}} diff --git a/checks/cloud/nifcloud/network/no_common_private_elb.go b/checks/cloud/nifcloud/network/no_common_private_elb.go index e7a08f41..b60be8de 100755 --- a/checks/cloud/nifcloud/network/no_common_private_elb.go +++ b/checks/cloud/nifcloud/network/no_common_private_elb.go @@ -28,7 +28,8 @@ var CheckNoCommonPrivateElasticLoadBalancer = rules.Register( Links: terraformNoCommonPrivateElasticLoadBalancerLinks, RemediationMarkdown: terraformNoCommonPrivateElasticLoadBalancerRemediationMarkdown, }, - Severity: severity.Low, + Severity: severity.Low, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, elb := range s.Nifcloud.Network.ElasticLoadBalancers { diff --git a/checks/cloud/nifcloud/network/no_common_private_elb.rego b/checks/cloud/nifcloud/network/no_common_private_elb.rego new file mode 100644 index 00000000..4173fe1d --- /dev/null +++ b/checks/cloud/nifcloud/network/no_common_private_elb.rego @@ -0,0 +1,38 @@ +# METADATA +# title: The elb has common private network +# description: | +# When handling sensitive data between servers, please consider using a private LAN to isolate the private side network from the shared network. +# scope: package +# schemas: +# - input: schema["cloud"] +# related_resources: +# - https://pfs.nifcloud.com/service/plan.htm +# custom: +# id: AVD-NIF-0019 +# avd_id: AVD-NIF-0019 +# provider: nifcloud +# service: network +# severity: LOW +# short_code: no-common-private-elb +# recommended_action: Use private LAN +# input: +# selector: +# - type: cloud +# subtypes: +# - service: network +# provider: nifcloud +# terraform: +# links: +# - https://registry.terraform.io/providers/nifcloud/nifcloud/latest/docs/resources/elb#network_id +# good_examples: checks/cloud/nifcloud/network/no_common_private_elb.tf.go +# bad_examples: checks/cloud/nifcloud/network/no_common_private_elb.tf.go +package builtin.nifcloud.network.nifcloud0019 + +import rego.v1 + +deny contains res if { + some elb in input.nifcloud.network.elasticloadbalancers + some ni in elb.networkinterfaces + ni.networkid.value == "net-COMMON_PRIVATE" + res := result.new("The elb has common private network", ni.networkid) +} diff --git a/checks/cloud/nifcloud/network/no_common_private_elb_test.go b/checks/cloud/nifcloud/network/no_common_private_elb_test.go deleted file mode 100644 index d047891b..00000000 --- a/checks/cloud/nifcloud/network/no_common_private_elb_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package network - -import ( - "testing" - - "github.com/aquasecurity/trivy/pkg/iac/providers/nifcloud/network" - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - - "github.com/aquasecurity/trivy/pkg/iac/scan" - - "github.com/aquasecurity/trivy/pkg/iac/state" - - "github.com/stretchr/testify/assert" -) - -func TestCheckNoCommonPrivateElasticLoadBalancer(t *testing.T) { - tests := []struct { - name string - input network.Network - expected bool - }{ - { - name: "NIFCLOUD elb with common private", - input: network.Network{ - ElasticLoadBalancers: []network.ElasticLoadBalancer{ - { - Metadata: trivyTypes.NewTestMetadata(), - NetworkInterfaces: []network.NetworkInterface{ - { - Metadata: trivyTypes.NewTestMetadata(), - NetworkID: trivyTypes.String("net-COMMON_PRIVATE", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "NIFCLOUD elb with private LAN", - input: network.Network{ - ElasticLoadBalancers: []network.ElasticLoadBalancer{ - { - Metadata: trivyTypes.NewTestMetadata(), - NetworkInterfaces: []network.NetworkInterface{ - { - Metadata: trivyTypes.NewTestMetadata(), - NetworkID: trivyTypes.String("net-some-private-lan", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: false, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.Nifcloud.Network = test.input - results := CheckNoCommonPrivateElasticLoadBalancer.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckNoCommonPrivateElasticLoadBalancer.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/checks/cloud/nifcloud/network/no_common_private_elb_test.rego b/checks/cloud/nifcloud/network/no_common_private_elb_test.rego new file mode 100644 index 00000000..4b80dee6 --- /dev/null +++ b/checks/cloud/nifcloud/network/no_common_private_elb_test.rego @@ -0,0 +1,20 @@ +package builtin.nifcloud.network.nifcloud0019_test + +import rego.v1 + +import data.builtin.nifcloud.network.nifcloud0019 as check +import data.lib.test + +test_allow_elb_with_private_lan if { + inp := {"nifcloud": {"network": {"elasticloadbalancers": [{"networkinterfaces": [{"networkid": {"value": "net-some-private-lan"}}]}]}}} + + res := check.deny with input as inp + res == set() +} + +test_deny_elb_with_common_private_lan if { + inp := {"nifcloud": {"network": {"elasticloadbalancers": [{"networkinterfaces": [{"networkid": {"value": "net-COMMON_PRIVATE"}}]}]}}} + + res := check.deny with input as inp + count(res) == 1 +} diff --git a/checks/cloud/nifcloud/network/no_common_private_router.go b/checks/cloud/nifcloud/network/no_common_private_router.go index 43a6e3f8..1fa88c6d 100755 --- a/checks/cloud/nifcloud/network/no_common_private_router.go +++ b/checks/cloud/nifcloud/network/no_common_private_router.go @@ -28,7 +28,8 @@ var CheckNoCommonPrivateRouter = rules.Register( Links: terraformNoCommonPrivateRouterLinks, RemediationMarkdown: terraformNoCommonPrivateRouterRemediationMarkdown, }, - Severity: severity.Low, + Severity: severity.Low, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, router := range s.Nifcloud.Network.Routers { diff --git a/checks/cloud/nifcloud/network/no_common_private_router.rego b/checks/cloud/nifcloud/network/no_common_private_router.rego new file mode 100644 index 00000000..9c5528fe --- /dev/null +++ b/checks/cloud/nifcloud/network/no_common_private_router.rego @@ -0,0 +1,38 @@ +# METADATA +# title: The router has common private network +# description: | +# When handling sensitive data between servers, please consider using a private LAN to isolate the private side network from the shared network. +# scope: package +# schemas: +# - input: schema["cloud"] +# related_resources: +# - https://pfs.nifcloud.com/service/plan.htm +# custom: +# id: AVD-NIF-0017 +# avd_id: AVD-NIF-0017 +# provider: nifcloud +# service: network +# severity: LOW +# short_code: no-common-private-router +# recommended_action: Use private LAN +# input: +# selector: +# - type: cloud +# subtypes: +# - service: network +# provider: nifcloud +# terraform: +# links: +# - https://registry.terraform.io/providers/nifcloud/nifcloud/latest/docs/resources/router#network_id +# good_examples: checks/cloud/nifcloud/network/no_common_private_router.tf.go +# bad_examples: checks/cloud/nifcloud/network/no_common_private_router.tf.go +package builtin.nifcloud.network.nifcloud0017 + +import rego.v1 + +deny contains res if { + some router in input.nifcloud.network.routers + some ni in router.networkinterfaces + ni.networkid.value == "net-COMMON_PRIVATE" + res := result.new("The router has common private network", ni.networkid) +} diff --git a/checks/cloud/nifcloud/network/no_common_private_router_test.go b/checks/cloud/nifcloud/network/no_common_private_router_test.go deleted file mode 100644 index 8187e3f6..00000000 --- a/checks/cloud/nifcloud/network/no_common_private_router_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package network - -import ( - "testing" - - "github.com/aquasecurity/trivy/pkg/iac/providers/nifcloud/network" - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - - "github.com/aquasecurity/trivy/pkg/iac/scan" - - "github.com/aquasecurity/trivy/pkg/iac/state" - - "github.com/stretchr/testify/assert" -) - -func TestCheckNoCommonPrivateRouter(t *testing.T) { - tests := []struct { - name string - input network.Network - expected bool - }{ - { - name: "NIFCLOUD router with common private", - input: network.Network{ - Routers: []network.Router{ - { - Metadata: trivyTypes.NewTestMetadata(), - NetworkInterfaces: []network.NetworkInterface{ - { - Metadata: trivyTypes.NewTestMetadata(), - NetworkID: trivyTypes.String("net-COMMON_PRIVATE", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "NIFCLOUD router with private LAN", - input: network.Network{ - Routers: []network.Router{ - { - Metadata: trivyTypes.NewTestMetadata(), - NetworkInterfaces: []network.NetworkInterface{ - { - Metadata: trivyTypes.NewTestMetadata(), - NetworkID: trivyTypes.String("net-some-private-lan", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: false, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.Nifcloud.Network = test.input - results := CheckNoCommonPrivateRouter.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckNoCommonPrivateRouter.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/checks/cloud/nifcloud/network/no_common_private_router_test.rego b/checks/cloud/nifcloud/network/no_common_private_router_test.rego new file mode 100644 index 00000000..87d8fd44 --- /dev/null +++ b/checks/cloud/nifcloud/network/no_common_private_router_test.rego @@ -0,0 +1,20 @@ +package builtin.nifcloud.network.nifcloud0017_test + +import rego.v1 + +import data.builtin.nifcloud.network.nifcloud0017 as check +import data.lib.test + +test_allow_with_private_lan if { + inp := {"nifcloud": {"network": {"routers": [{"networkinterfaces": [{"networkid": {"value": "net-some-private-lan"}}]}]}}} + + res := check.deny with input as inp + res == set() +} + +test_deny_with_common_private_lan if { + inp := {"nifcloud": {"network": {"routers": [{"networkinterfaces": [{"networkid": {"value": "net-COMMON_PRIVATE"}}]}]}}} + + res := check.deny with input as inp + count(res) == 1 +} diff --git a/checks/cloud/nifcloud/network/use_secure_tls_policy.go b/checks/cloud/nifcloud/network/use_secure_tls_policy.go index 44408f40..4a133e1b 100755 --- a/checks/cloud/nifcloud/network/use_secure_tls_policy.go +++ b/checks/cloud/nifcloud/network/use_secure_tls_policy.go @@ -41,7 +41,8 @@ var CheckUseSecureTlsPolicy = rules.Register( Links: terraformUseSecureTlsPolicyLinks, RemediationMarkdown: terraformUseSecureTlsPolicyRemediationMarkdown, }, - Severity: severity.Critical, + Severity: severity.Critical, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, lb := range s.Nifcloud.Network.LoadBalancers { diff --git a/checks/cloud/nifcloud/network/use_secure_tls_policy.rego b/checks/cloud/nifcloud/network/use_secure_tls_policy.rego new file mode 100644 index 00000000..4a1b2a66 --- /dev/null +++ b/checks/cloud/nifcloud/network/use_secure_tls_policy.rego @@ -0,0 +1,54 @@ +# METADATA +# title: An outdated SSL policy is in use by a load balancer. +# description: | +# You should not use outdated/insecure TLS versions for encryption. You should be using TLS v1.2+. +# scope: package +# schemas: +# - input: schema["cloud"] +# related_resources: +# - https://pfs.nifcloud.com/service/lb_l4.htm +# custom: +# id: AVD-NIF-0020 +# avd_id: AVD-NIF-0020 +# provider: nifcloud +# service: network +# severity: CRITICAL +# short_code: use-secure-tls-policy +# recommended_action: Use a more recent TLS/SSL policy for the load balancer +# input: +# selector: +# - type: cloud +# subtypes: +# - service: network +# provider: nifcloud +# terraform: +# links: +# - https://registry.terraform.io/providers/nifcloud/nifcloud/latest/docs/resources/load_balancer#ssl_policy_name +# - https://registry.terraform.io/providers/nifcloud/nifcloud/latest/docs/resources/load_balancer_listener#ssl_policy_name +# good_examples: checks/cloud/nifcloud/network/use_secure_tls_policy.tf.go +# bad_examples: checks/cloud/nifcloud/network/use_secure_tls_policy.tf.go +package builtin.nifcloud.network.nifcloud0020 + +import rego.v1 + +outdated_sslpolicies = { + "", + "1", + "Standard Ciphers A ver1", + "2", + "Standard Ciphers B ver1", + "3", + "Standard Ciphers C ver1", + "5", + "Ats Ciphers A ver1", + "8", + "Ats Ciphers D ver1", +} + +deny contains res if { + some lb in input.nifcloud.network.loadbalancers + some listener in lb.listeners + listener.protocol.value == "HTTPS" + listener.tlspolicy.value in outdated_sslpolicies + res := result.new("Listener uses an outdated TLS policy.", listener.tlspolicy) +} diff --git a/checks/cloud/nifcloud/network/use_secure_tls_policy_test.go b/checks/cloud/nifcloud/network/use_secure_tls_policy_test.go deleted file mode 100644 index dded26e6..00000000 --- a/checks/cloud/nifcloud/network/use_secure_tls_policy_test.go +++ /dev/null @@ -1,92 +0,0 @@ -package network - -import ( - "testing" - - "github.com/aquasecurity/trivy/pkg/iac/providers/nifcloud/network" - "github.com/aquasecurity/trivy/pkg/iac/scan" - "github.com/aquasecurity/trivy/pkg/iac/state" - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - "github.com/stretchr/testify/assert" -) - -func TestCheckUseSecureTlsPolicy(t *testing.T) { - tests := []struct { - name string - input network.Network - expected bool - }{ - { - name: "Load balancer listener using TLS v1.0", - input: network.Network{ - LoadBalancers: []network.LoadBalancer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Listeners: []network.LoadBalancerListener{ - { - Metadata: trivyTypes.NewTestMetadata(), - TLSPolicy: trivyTypes.String("Standard Ciphers A ver1", trivyTypes.NewTestMetadata()), - Protocol: trivyTypes.String("HTTPS", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "Load balancer listener using TLS v1.2", - input: network.Network{ - LoadBalancers: []network.LoadBalancer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Listeners: []network.LoadBalancerListener{ - { - Metadata: trivyTypes.NewTestMetadata(), - TLSPolicy: trivyTypes.String("Standard Ciphers D ver1", trivyTypes.NewTestMetadata()), - Protocol: trivyTypes.String("HTTPS", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: false, - }, - { - name: "Load balancer listener using ICMP", - input: network.Network{ - LoadBalancers: []network.LoadBalancer{ - { - Metadata: trivyTypes.NewTestMetadata(), - Listeners: []network.LoadBalancerListener{ - { - Metadata: trivyTypes.NewTestMetadata(), - TLSPolicy: trivyTypes.String("", trivyTypes.NewTestMetadata()), - Protocol: trivyTypes.String("ICMP", trivyTypes.NewTestMetadata()), - }, - }, - }, - }, - }, - expected: false, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.Nifcloud.Network = test.input - results := CheckUseSecureTlsPolicy.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckUseSecureTlsPolicy.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/checks/cloud/nifcloud/network/use_secure_tls_policy_test.rego b/checks/cloud/nifcloud/network/use_secure_tls_policy_test.rego new file mode 100644 index 00000000..5ad509b1 --- /dev/null +++ b/checks/cloud/nifcloud/network/use_secure_tls_policy_test.rego @@ -0,0 +1,36 @@ +package builtin.nifcloud.network.nifcloud0020_test + +import rego.v1 + +import data.builtin.nifcloud.network.nifcloud0020 as check +import data.lib.test + +test_allow_lb_using_tls_v12 if { + inp := {"nifcloud": {"network": {"loadbalancers": [{"listeners": [{ + "protocol": {"value": "HTTPS"}, + "tlspolicy": {"value": "Standard Ciphers D ver1"}, + }]}]}}} + + res := check.deny with input as inp + res == set() +} + +test_allow_lb_using_ICMP if { + inp := {"nifcloud": {"network": {"loadbalancers": [{"listeners": [{ + "protocol": {"value": "ICMP"}, + "tlspolicy": {"value": ""}, + }]}]}}} + + res := check.deny with input as inp + res == set() +} + +test_deny_lb_using_tls_v1 if { + inp := {"nifcloud": {"network": {"loadbalancers": [{"listeners": [{ + "protocol": {"value": "HTTPS"}, + "tlspolicy": {"value": "Standard Ciphers A ver1"}, + }]}]}}} + + res := check.deny with input as inp + count(res) == 1 +} diff --git a/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates.go b/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates.go index 8b3617d6..4669af56 100644 --- a/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates.go +++ b/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates.go @@ -32,7 +32,8 @@ recommended to delete expired certificates. Links: []string{ "https://pfs.nifcloud.com/help/ssl/del.htm", }, - Severity: severity.Low, + Severity: severity.Low, + Deprecated: true, }, func(s *state.State) (results scan.Results) { for _, certificate := range s.Nifcloud.SSLCertificate.ServerCertificates { diff --git a/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates.rego b/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates.rego new file mode 100644 index 00000000..daf1dafd --- /dev/null +++ b/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates.rego @@ -0,0 +1,38 @@ +# METADATA +# title: Delete expired SSL certificates +# description: | +# Removing expired SSL/TLS certificates eliminates the risk that an invalid certificate will be +# +# deployed accidentally to a resource such as NIFCLOUD Load Balancer(L4LB), which candamage the +# +# credibility of the application/website behind the L4LB. As a best practice, it is +# +# recommended to delete expired certificates. +# scope: package +# schemas: +# - input: schema["cloud"] +# related_resources: +# - https://pfs.nifcloud.com/help/ssl/del.htm +# custom: +# id: AVD-NIF-0006 +# avd_id: AVD-NIF-0006 +# provider: nifcloud +# service: ssl-certificate +# severity: LOW +# short_code: remove-expired-certificates +# recommended_action: Remove expired certificates +# input: +# selector: +# - type: cloud +# subtypes: +# - service: sslcertificate +# provider: nifcloud +package builtin.nifcloud.sslcertificate.nifcloud0006 + +import rego.v1 + +deny contains res if { + some cert in input.nifcloud.sslcertificate.servercertificates + time.parse_rfc3339_ns(cert.expiration.value) - time.now_ns() <= 0 + res := result.new("Certificate has expired.", cert) +} diff --git a/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates_test.go b/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates_test.go deleted file mode 100644 index 5f0bb514..00000000 --- a/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package sslcertificate - -import ( - "testing" - "time" - - "github.com/aquasecurity/trivy/pkg/iac/providers/nifcloud/sslcertificate" - "github.com/aquasecurity/trivy/pkg/iac/scan" - "github.com/aquasecurity/trivy/pkg/iac/state" - trivyTypes "github.com/aquasecurity/trivy/pkg/iac/types" - "github.com/stretchr/testify/assert" -) - -func TestCheckRemoveExpiredCertificates(t *testing.T) { - tests := []struct { - name string - input sslcertificate.SSLCertificate - expected bool - }{ - { - name: "No certs", - input: sslcertificate.SSLCertificate{}, - expected: false, - }, - { - name: "Valid cert", - input: sslcertificate.SSLCertificate{ - ServerCertificates: []sslcertificate.ServerCertificate{ - { - Metadata: trivyTypes.NewTestMetadata(), - Expiration: trivyTypes.Time(time.Now().Add(time.Hour), trivyTypes.NewTestMetadata()), - }, - }, - }, - expected: false, - }, - { - name: "Expired cert", - input: sslcertificate.SSLCertificate{ - ServerCertificates: []sslcertificate.ServerCertificate{ - { - Metadata: trivyTypes.NewTestMetadata(), - Expiration: trivyTypes.Time(time.Now().Add(-time.Hour), trivyTypes.NewTestMetadata()), - }, - }, - }, - expected: true, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - var testState state.State - testState.Nifcloud.SSLCertificate = test.input - results := CheckRemoveExpiredCertificates.Evaluate(&testState) - var found bool - for _, result := range results { - if result.Status() == scan.StatusFailed && result.Rule().LongID() == CheckRemoveExpiredCertificates.LongID() { - found = true - } - } - if test.expected { - assert.True(t, found, "Rule should have been found") - } else { - assert.False(t, found, "Rule should not have been found") - } - }) - } -} diff --git a/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates_test.rego b/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates_test.rego new file mode 100644 index 00000000..e8806943 --- /dev/null +++ b/checks/cloud/nifcloud/sslcertificate/remove_expired_certificates_test.rego @@ -0,0 +1,20 @@ +package builtin.nifcloud.sslcertificate.nifcloud0006_test + +import rego.v1 + +import data.builtin.nifcloud.sslcertificate.nifcloud0006 as check +import data.lib.test + +test_allow_not_expired_certificate if { + inp := {"nifcloud": {"sslcertificate": {"servercertificates": [{"expiration": {"value": time.format(time.now_ns() + 3600000000000)}}]}}} + + res := check.deny with input as inp + res == set() +} + +test_deny_expired_certificate if { + inp := {"nifcloud": {"sslcertificate": {"servercertificates": [{"expiration": {"value": time.format(time.now_ns() - 3600000000000)}}]}}} + + res := check.deny with input as inp + count(res) == 1 +}