From 13f595fcee6843589575b21c069dc7392af19734 Mon Sep 17 00:00:00 2001 From: Liam Galvin Date: Sat, 11 Jan 2020 14:25:47 +0000 Subject: [PATCH 1/3] Add links for each rule and rename code -> rule id --- README.md | 4 ++-- internal/app/tfsec/aws_acl_test.go | 4 ++-- internal/app/tfsec/aws_bucket_logging_test.go | 4 ++-- internal/app/tfsec/aws_classic_test.go | 4 ++-- internal/app/tfsec/aws_http_test.go | 4 ++-- .../aws_missing_description_for_security_group_test.go | 4 ++-- internal/app/tfsec/aws_not_internal_test.go | 4 ++-- .../app/tfsec/aws_open_security_group_rule_test.go | 4 ++-- internal/app/tfsec/aws_open_security_group_test.go | 4 ++-- internal/app/tfsec/aws_outdated_ssl_test.go | 4 ++-- internal/app/tfsec/aws_public_ip_test.go | 4 ++-- internal/app/tfsec/aws_public_test.go | 4 ++-- ...aws_task_definition_includes_sensitive_data_test.go | 4 ++-- .../app/tfsec/aws_unencrypted_block_device_test.go | 4 ++-- internal/app/tfsec/aws_unencrypted_s3_bucket_test.go | 4 ++-- internal/app/tfsec/aws_unencrypted_sns_topic_test.go | 4 ++-- internal/app/tfsec/aws_unencrypted_sqs_queue_test.go | 4 ++-- .../tfsec/azurerm_open_network_security_rules_test.go | 4 ++-- .../tfsec/azurerm_unencrypted_data_lake_store_test.go | 4 ++-- .../app/tfsec/azurerm_unencrypted_managed_disk_test.go | 4 ++-- ...irtual_machine_with_password_authentication_test.go | 4 ++-- internal/app/tfsec/checks/aws_acl.go | 2 +- internal/app/tfsec/checks/aws_bucket_logging.go | 2 +- internal/app/tfsec/checks/aws_classic.go | 2 +- internal/app/tfsec/checks/aws_http.go | 2 +- .../aws_missing_description_in_security_group.go | 2 +- internal/app/tfsec/checks/aws_not_internal.go | 2 +- .../app/tfsec/checks/aws_open_security_group_rules.go | 4 ++-- internal/app/tfsec/checks/aws_open_security_groups.go | 4 ++-- internal/app/tfsec/checks/aws_outdated_ssl.go | 2 +- internal/app/tfsec/checks/aws_public.go | 2 +- internal/app/tfsec/checks/aws_public_ip.go | 2 +- .../aws_task_definition_includes_sensitive_data.go | 2 +- .../app/tfsec/checks/aws_unencrypted_block_device.go | 2 +- internal/app/tfsec/checks/aws_unencrypted_s3_bucket.go | 2 +- internal/app/tfsec/checks/aws_unencrypted_sns_topic.go | 2 +- internal/app/tfsec/checks/aws_unencrypted_sqs_queue.go | 2 +- .../checks/azurerm_open_network_security_rules.go | 4 ++-- .../checks/azurerm_unencrypted_data_lake_store.go | 2 +- .../tfsec/checks/azurerm_unencrypted_managed_disk.go | 2 +- ...erm_virtual_machine_with_password_authentication.go | 2 +- .../app/tfsec/checks/generic_sensitive_attributes.go | 2 +- internal/app/tfsec/checks/generic_sensitive_locals.go | 2 +- .../app/tfsec/checks/generic_sensitive_variables.go | 2 +- internal/app/tfsec/checks/gke_abac_enabled.go | 2 +- .../app/tfsec/checks/google_open_firewall_rules.go | 4 ++-- internal/app/tfsec/checks/google_unencrypted_disk.go | 2 +- .../tfsec/checks/google_unencrypted_storage_bucket.go | 2 +- internal/app/tfsec/formatters/checkstyle.go | 3 ++- internal/app/tfsec/formatters/csv.go | 5 +++-- internal/app/tfsec/formatters/default.go | 3 ++- .../app/tfsec/generic_sensitive_attributes_test.go | 4 ++-- internal/app/tfsec/generic_sensitive_locals_test.go | 4 ++-- internal/app/tfsec/generic_sensitive_variables_test.go | 4 ++-- internal/app/tfsec/gke_abac_enabled_test.go | 4 ++-- internal/app/tfsec/google_open_firewall_rule_test.go | 8 ++++---- internal/app/tfsec/google_unencrypted_disk_test.go | 4 ++-- .../tfsec/google_unencrypted_storage_bucket_test.go | 4 ++-- internal/app/tfsec/ignore_test.go | 2 +- internal/app/tfsec/module_scan_test.go | 4 ++-- internal/app/tfsec/scanner/check.go | 10 +++++----- internal/app/tfsec/scanner/result.go | 3 ++- internal/app/tfsec/scanner/scanner.go | 5 +++-- internal/app/tfsec/setup_test.go | 10 +++++----- 64 files changed, 114 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index cd21bef8b3..9d06065fe9 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ docker run --rm -it -v "$(pwd):/workdir" tfsec . ## Ignoring Warnings You may wish to ignore some warnings. If you'd like to do so, you can -simply add a comment containing `tfsec:ignore:` to the offending +simply add a comment containing `tfsec:ignore:` to the offending line in your templates. If the problem refers to a block of code, such as a multiline string, you can add the comment on the line above the block, by itself. @@ -105,7 +105,7 @@ tfsec output for the line number of the discovered problem. Currently, checks are mostly limited to AWS/Azure/GCP resources, but there are also checks which are provider agnostic. -| Code | Provider | Description | +| Rule | Provider | Description | |---------|----------|-------------| | GEN001 | * | Potentially sensitive data stored in "default" value of variable. | GEN002 | * | Potentially sensitive data stored in local value. diff --git a/internal/app/tfsec/aws_acl_test.go b/internal/app/tfsec/aws_acl_test.go index d0555e3ef8..590d6d6d21 100644 --- a/internal/app/tfsec/aws_acl_test.go +++ b/internal/app/tfsec/aws_acl_test.go @@ -13,8 +13,8 @@ func Test_AWSACL(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check aws_s3_bucket with acl=public-read", diff --git a/internal/app/tfsec/aws_bucket_logging_test.go b/internal/app/tfsec/aws_bucket_logging_test.go index fcb0148b44..93c33a8bdd 100644 --- a/internal/app/tfsec/aws_bucket_logging_test.go +++ b/internal/app/tfsec/aws_bucket_logging_test.go @@ -13,8 +13,8 @@ func Test_AWSBucketLogging(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check bucket with logging disabled", diff --git a/internal/app/tfsec/aws_classic_test.go b/internal/app/tfsec/aws_classic_test.go index e4cda0b693..048f56426a 100644 --- a/internal/app/tfsec/aws_classic_test.go +++ b/internal/app/tfsec/aws_classic_test.go @@ -13,8 +13,8 @@ func Test_AWSClassicUsage(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check aws_db_security_group", diff --git a/internal/app/tfsec/aws_http_test.go b/internal/app/tfsec/aws_http_test.go index 5aa7bf41a6..8cafafb368 100644 --- a/internal/app/tfsec/aws_http_test.go +++ b/internal/app/tfsec/aws_http_test.go @@ -13,8 +13,8 @@ func Test_AWSPlainHTTP(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check aws_alb_listener using plain HTTP", diff --git a/internal/app/tfsec/aws_missing_description_for_security_group_test.go b/internal/app/tfsec/aws_missing_description_for_security_group_test.go index 8a1f0b7e09..71e9651b5b 100644 --- a/internal/app/tfsec/aws_missing_description_for_security_group_test.go +++ b/internal/app/tfsec/aws_missing_description_for_security_group_test.go @@ -13,8 +13,8 @@ func Test_AWSMissingDescriptionForSecurityGroup(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check aws_security_group without description", diff --git a/internal/app/tfsec/aws_not_internal_test.go b/internal/app/tfsec/aws_not_internal_test.go index db1f6af885..5e567f3337 100644 --- a/internal/app/tfsec/aws_not_internal_test.go +++ b/internal/app/tfsec/aws_not_internal_test.go @@ -13,8 +13,8 @@ func Test_AWSNotInternal(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check aws_alb when not internal", diff --git a/internal/app/tfsec/aws_open_security_group_rule_test.go b/internal/app/tfsec/aws_open_security_group_rule_test.go index 267b3f6dbf..419d2b5b9c 100644 --- a/internal/app/tfsec/aws_open_security_group_rule_test.go +++ b/internal/app/tfsec/aws_open_security_group_rule_test.go @@ -13,8 +13,8 @@ func Test_AWSOpenSecurityGroupRule(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check aws_security_group_rule ingress on 0.0.0.0/0", diff --git a/internal/app/tfsec/aws_open_security_group_test.go b/internal/app/tfsec/aws_open_security_group_test.go index f9b05b37c7..520f796a6a 100644 --- a/internal/app/tfsec/aws_open_security_group_test.go +++ b/internal/app/tfsec/aws_open_security_group_test.go @@ -13,8 +13,8 @@ func Test_AWSOpenSecurityGroup(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check aws_security_group ingress on 0.0.0.0/0", diff --git a/internal/app/tfsec/aws_outdated_ssl_test.go b/internal/app/tfsec/aws_outdated_ssl_test.go index b2c7f1296b..464dad5d53 100644 --- a/internal/app/tfsec/aws_outdated_ssl_test.go +++ b/internal/app/tfsec/aws_outdated_ssl_test.go @@ -13,8 +13,8 @@ func Test_AWSOutdatedSSLPolicy(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check aws_alb_listener with outdated policy", diff --git a/internal/app/tfsec/aws_public_ip_test.go b/internal/app/tfsec/aws_public_ip_test.go index 2b881d30ea..088f6b5d03 100644 --- a/internal/app/tfsec/aws_public_ip_test.go +++ b/internal/app/tfsec/aws_public_ip_test.go @@ -13,8 +13,8 @@ func Test_AWSPublicIP(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check aws_launch_configuration with public ip associated", diff --git a/internal/app/tfsec/aws_public_test.go b/internal/app/tfsec/aws_public_test.go index 81e5228e9d..a058ad6f12 100644 --- a/internal/app/tfsec/aws_public_test.go +++ b/internal/app/tfsec/aws_public_test.go @@ -13,8 +13,8 @@ func Test_AWSPublic(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check aws_db_instance when publicly exposed", diff --git a/internal/app/tfsec/aws_task_definition_includes_sensitive_data_test.go b/internal/app/tfsec/aws_task_definition_includes_sensitive_data_test.go index 3c279f0e72..87eff30887 100644 --- a/internal/app/tfsec/aws_task_definition_includes_sensitive_data_test.go +++ b/internal/app/tfsec/aws_task_definition_includes_sensitive_data_test.go @@ -13,8 +13,8 @@ func Test_AWSTaskDefinitionIncludesSensitiveData(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check aws_ecs_task_definition when sensitive env vars are included", diff --git a/internal/app/tfsec/aws_unencrypted_block_device_test.go b/internal/app/tfsec/aws_unencrypted_block_device_test.go index 21054c6f5b..8b97ddc89f 100644 --- a/internal/app/tfsec/aws_unencrypted_block_device_test.go +++ b/internal/app/tfsec/aws_unencrypted_block_device_test.go @@ -13,8 +13,8 @@ func Test_AWSUnencryptedBlockDevice(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check no root_block_device configured in launch configuration", diff --git a/internal/app/tfsec/aws_unencrypted_s3_bucket_test.go b/internal/app/tfsec/aws_unencrypted_s3_bucket_test.go index 1d7420a0d6..24e5320659 100644 --- a/internal/app/tfsec/aws_unencrypted_s3_bucket_test.go +++ b/internal/app/tfsec/aws_unencrypted_s3_bucket_test.go @@ -13,8 +13,8 @@ func Test_AWSUnencryptedS3Bucket(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check no server_side_encryption_configuration aws_s3_bucket", diff --git a/internal/app/tfsec/aws_unencrypted_sns_topic_test.go b/internal/app/tfsec/aws_unencrypted_sns_topic_test.go index 19fb3e60ca..0a5cb59b41 100644 --- a/internal/app/tfsec/aws_unencrypted_sns_topic_test.go +++ b/internal/app/tfsec/aws_unencrypted_sns_topic_test.go @@ -13,8 +13,8 @@ func Test_AWSUnencryptedSNSTopic(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check no encryption key id specified for aws_sns_topic", diff --git a/internal/app/tfsec/aws_unencrypted_sqs_queue_test.go b/internal/app/tfsec/aws_unencrypted_sqs_queue_test.go index b6ca00b972..8e9c5ec35d 100644 --- a/internal/app/tfsec/aws_unencrypted_sqs_queue_test.go +++ b/internal/app/tfsec/aws_unencrypted_sqs_queue_test.go @@ -13,8 +13,8 @@ func Test_AWSUnencryptedSQSQueue(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check no encryption key id specified for aws_sqs_queue", diff --git a/internal/app/tfsec/azurerm_open_network_security_rules_test.go b/internal/app/tfsec/azurerm_open_network_security_rules_test.go index fea0273429..a1b3178bec 100644 --- a/internal/app/tfsec/azurerm_open_network_security_rules_test.go +++ b/internal/app/tfsec/azurerm_open_network_security_rules_test.go @@ -13,8 +13,8 @@ func Test_AzureOpenNetworkSecurityGroupRule(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check azurerm_network_security_rule inbound on 0.0.0.0/0", diff --git a/internal/app/tfsec/azurerm_unencrypted_data_lake_store_test.go b/internal/app/tfsec/azurerm_unencrypted_data_lake_store_test.go index d176352b6a..303ee0073f 100644 --- a/internal/app/tfsec/azurerm_unencrypted_data_lake_store_test.go +++ b/internal/app/tfsec/azurerm_unencrypted_data_lake_store_test.go @@ -13,8 +13,8 @@ func Test_AzureUnencryptedDataLakeStore(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check azurerm_data_lake_store with encryption disabled", diff --git a/internal/app/tfsec/azurerm_unencrypted_managed_disk_test.go b/internal/app/tfsec/azurerm_unencrypted_managed_disk_test.go index b67f81f815..7da1b4de3a 100644 --- a/internal/app/tfsec/azurerm_unencrypted_managed_disk_test.go +++ b/internal/app/tfsec/azurerm_unencrypted_managed_disk_test.go @@ -13,8 +13,8 @@ func Test_AzureUnencryptedManagedDisk(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check azurerm_managed_disk with no encryption_settings", diff --git a/internal/app/tfsec/azurerm_virtual_machine_with_password_authentication_test.go b/internal/app/tfsec/azurerm_virtual_machine_with_password_authentication_test.go index a6b0c7f3f5..a865b0f301 100644 --- a/internal/app/tfsec/azurerm_virtual_machine_with_password_authentication_test.go +++ b/internal/app/tfsec/azurerm_virtual_machine_with_password_authentication_test.go @@ -13,8 +13,8 @@ func Test_AzureVMWithPasswordAuth(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check azurerm_virtual_machine with password auth", diff --git a/internal/app/tfsec/checks/aws_acl.go b/internal/app/tfsec/checks/aws_acl.go index b7c03bad55..37cd0b0818 100644 --- a/internal/app/tfsec/checks/aws_acl.go +++ b/internal/app/tfsec/checks/aws_acl.go @@ -11,7 +11,7 @@ import ( ) // AWSBadBucketACL See https://github.com/liamg/tfsec#included-checks for check info -const AWSBadBucketACL scanner.CheckCode = "AWS001" +const AWSBadBucketACL scanner.RuleID = "AWS001" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_bucket_logging.go b/internal/app/tfsec/checks/aws_bucket_logging.go index f88b6c1a41..6fa681a73f 100644 --- a/internal/app/tfsec/checks/aws_bucket_logging.go +++ b/internal/app/tfsec/checks/aws_bucket_logging.go @@ -9,7 +9,7 @@ import ( ) // AWSNoBucketLogging See https://github.com/liamg/tfsec#included-checks for check info -const AWSNoBucketLogging scanner.CheckCode = "AWS002" +const AWSNoBucketLogging scanner.RuleID = "AWS002" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_classic.go b/internal/app/tfsec/checks/aws_classic.go index 4d142008f5..392e493954 100644 --- a/internal/app/tfsec/checks/aws_classic.go +++ b/internal/app/tfsec/checks/aws_classic.go @@ -9,7 +9,7 @@ import ( ) // AWSClassicUsage See https://github.com/liamg/tfsec#included-checks for check info -const AWSClassicUsage scanner.CheckCode = "AWS003" +const AWSClassicUsage scanner.RuleID = "AWS003" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_http.go b/internal/app/tfsec/checks/aws_http.go index a58d305412..c4c3b3db1c 100644 --- a/internal/app/tfsec/checks/aws_http.go +++ b/internal/app/tfsec/checks/aws_http.go @@ -10,7 +10,7 @@ import ( ) // AWSPlainHTTP See https://github.com/liamg/tfsec#included-checks for check info -const AWSPlainHTTP scanner.CheckCode = "AWS004" +const AWSPlainHTTP scanner.RuleID = "AWS004" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_missing_description_in_security_group.go b/internal/app/tfsec/checks/aws_missing_description_in_security_group.go index be02e12e61..f7e1e3b41e 100644 --- a/internal/app/tfsec/checks/aws_missing_description_in_security_group.go +++ b/internal/app/tfsec/checks/aws_missing_description_in_security_group.go @@ -10,7 +10,7 @@ import ( ) // AWSNoDescriptionInSecurityGroup See https://github.com/liamg/tfsec#included-checks for check info -const AWSNoDescriptionInSecurityGroup scanner.CheckCode = "AWS018" +const AWSNoDescriptionInSecurityGroup scanner.RuleID = "AWS018" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_not_internal.go b/internal/app/tfsec/checks/aws_not_internal.go index 38dcf51ad6..755549f9a3 100644 --- a/internal/app/tfsec/checks/aws_not_internal.go +++ b/internal/app/tfsec/checks/aws_not_internal.go @@ -11,7 +11,7 @@ import ( ) // AWSExternallyExposedLoadBalancer See https://github.com/liamg/tfsec#included-checks for check info -const AWSExternallyExposedLoadBalancer scanner.CheckCode = "AWS005" +const AWSExternallyExposedLoadBalancer scanner.RuleID = "AWS005" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_open_security_group_rules.go b/internal/app/tfsec/checks/aws_open_security_group_rules.go index 1528fd5e6b..7ab61297d1 100644 --- a/internal/app/tfsec/checks/aws_open_security_group_rules.go +++ b/internal/app/tfsec/checks/aws_open_security_group_rules.go @@ -12,10 +12,10 @@ import ( ) // AWSOpenIngressSecurityGroupRule See https://github.com/liamg/tfsec#included-checks for check info -const AWSOpenIngressSecurityGroupRule scanner.CheckCode = "AWS006" +const AWSOpenIngressSecurityGroupRule scanner.RuleID = "AWS006" // AWSOpenEgressSecurityGroupRule See https://github.com/liamg/tfsec#included-checks for check info -const AWSOpenEgressSecurityGroupRule scanner.CheckCode = "AWS007" +const AWSOpenEgressSecurityGroupRule scanner.RuleID = "AWS007" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_open_security_groups.go b/internal/app/tfsec/checks/aws_open_security_groups.go index 618652dd9a..cdf640a401 100644 --- a/internal/app/tfsec/checks/aws_open_security_groups.go +++ b/internal/app/tfsec/checks/aws_open_security_groups.go @@ -10,10 +10,10 @@ import ( ) // AWSOpenIngressSecurityGroupInlineRule See https://github.com/liamg/tfsec#included-checks for check info -const AWSOpenIngressSecurityGroupInlineRule scanner.CheckCode = "AWS008" +const AWSOpenIngressSecurityGroupInlineRule scanner.RuleID = "AWS008" // AWSOpenEgressSecurityGroupInlineRule See https://github.com/liamg/tfsec#included-checks for check info -const AWSOpenEgressSecurityGroupInlineRule scanner.CheckCode = "AWS009" +const AWSOpenEgressSecurityGroupInlineRule scanner.RuleID = "AWS009" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_outdated_ssl.go b/internal/app/tfsec/checks/aws_outdated_ssl.go index 967ad4f3b5..25f9426417 100644 --- a/internal/app/tfsec/checks/aws_outdated_ssl.go +++ b/internal/app/tfsec/checks/aws_outdated_ssl.go @@ -11,7 +11,7 @@ import ( ) // AWSOutdatedSSLPolicy See https://github.com/liamg/tfsec#included-checks for check info -const AWSOutdatedSSLPolicy scanner.CheckCode = "AWS010" +const AWSOutdatedSSLPolicy scanner.RuleID = "AWS010" var outdatedSSLPolicies = []string{ "ELBSecurityPolicy-2015-05", diff --git a/internal/app/tfsec/checks/aws_public.go b/internal/app/tfsec/checks/aws_public.go index 8648034457..149d9b6a28 100644 --- a/internal/app/tfsec/checks/aws_public.go +++ b/internal/app/tfsec/checks/aws_public.go @@ -11,7 +11,7 @@ import ( ) // AWSPubliclyAccessibleResource See https://github.com/liamg/tfsec#included-checks for check info -const AWSPubliclyAccessibleResource scanner.CheckCode = "AWS011" +const AWSPubliclyAccessibleResource scanner.RuleID = "AWS011" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_public_ip.go b/internal/app/tfsec/checks/aws_public_ip.go index a6412dbb33..1d58e12dd7 100644 --- a/internal/app/tfsec/checks/aws_public_ip.go +++ b/internal/app/tfsec/checks/aws_public_ip.go @@ -11,7 +11,7 @@ import ( ) // AWSResourceHasPublicIP See https://github.com/liamg/tfsec#included-checks for check info -const AWSResourceHasPublicIP scanner.CheckCode = "AWS012" +const AWSResourceHasPublicIP scanner.RuleID = "AWS012" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_task_definition_includes_sensitive_data.go b/internal/app/tfsec/checks/aws_task_definition_includes_sensitive_data.go index aa3ca6a7ee..8197597f18 100644 --- a/internal/app/tfsec/checks/aws_task_definition_includes_sensitive_data.go +++ b/internal/app/tfsec/checks/aws_task_definition_includes_sensitive_data.go @@ -14,7 +14,7 @@ import ( ) // AWSTaskDefinitionWithSensitiveEnvironmentVariables See https://github.com/liamg/tfsec#included-checks for check info -const AWSTaskDefinitionWithSensitiveEnvironmentVariables scanner.CheckCode = "AWS013" +const AWSTaskDefinitionWithSensitiveEnvironmentVariables scanner.RuleID = "AWS013" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_unencrypted_block_device.go b/internal/app/tfsec/checks/aws_unencrypted_block_device.go index cc1e12aad9..52410bda63 100644 --- a/internal/app/tfsec/checks/aws_unencrypted_block_device.go +++ b/internal/app/tfsec/checks/aws_unencrypted_block_device.go @@ -11,7 +11,7 @@ import ( ) // AWSLaunchConfigurationWithUnencryptedBlockDevice See https://github.com/liamg/tfsec#included-checks for check info -const AWSLaunchConfigurationWithUnencryptedBlockDevice scanner.CheckCode = "AWS014" +const AWSLaunchConfigurationWithUnencryptedBlockDevice scanner.RuleID = "AWS014" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_unencrypted_s3_bucket.go b/internal/app/tfsec/checks/aws_unencrypted_s3_bucket.go index e4ffccf7f3..67ec8a0f37 100644 --- a/internal/app/tfsec/checks/aws_unencrypted_s3_bucket.go +++ b/internal/app/tfsec/checks/aws_unencrypted_s3_bucket.go @@ -9,7 +9,7 @@ import ( ) // AWSUnencryptedS3Bucket See https://github.com/liamg/tfsec#included-checks for check info -const AWSUnencryptedS3Bucket scanner.CheckCode = "AWS017" +const AWSUnencryptedS3Bucket scanner.RuleID = "AWS017" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_unencrypted_sns_topic.go b/internal/app/tfsec/checks/aws_unencrypted_sns_topic.go index 1265b25e02..24d0af0730 100644 --- a/internal/app/tfsec/checks/aws_unencrypted_sns_topic.go +++ b/internal/app/tfsec/checks/aws_unencrypted_sns_topic.go @@ -11,7 +11,7 @@ import ( ) // AWSUnencryptedSNSTopic See https://github.com/liamg/tfsec#included-checks for check info -const AWSUnencryptedSNSTopic scanner.CheckCode = "AWS016" +const AWSUnencryptedSNSTopic scanner.RuleID = "AWS016" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/aws_unencrypted_sqs_queue.go b/internal/app/tfsec/checks/aws_unencrypted_sqs_queue.go index 8a93f35598..a38d140c45 100644 --- a/internal/app/tfsec/checks/aws_unencrypted_sqs_queue.go +++ b/internal/app/tfsec/checks/aws_unencrypted_sqs_queue.go @@ -11,7 +11,7 @@ import ( ) // AWSUnencryptedSQSQueue See https://github.com/liamg/tfsec#included-checks for check info -const AWSUnencryptedSQSQueue scanner.CheckCode = "AWS015" +const AWSUnencryptedSQSQueue scanner.RuleID = "AWS015" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/azurerm_open_network_security_rules.go b/internal/app/tfsec/checks/azurerm_open_network_security_rules.go index 0b29927d71..cb65e76283 100644 --- a/internal/app/tfsec/checks/azurerm_open_network_security_rules.go +++ b/internal/app/tfsec/checks/azurerm_open_network_security_rules.go @@ -12,10 +12,10 @@ import ( ) // AzureOpenInboundNetworkSecurityGroupRule See https://github.com/liamg/tfsec#included-checks for check info -const AzureOpenInboundNetworkSecurityGroupRule scanner.CheckCode = "AZU001" +const AzureOpenInboundNetworkSecurityGroupRule scanner.RuleID = "AZU001" // AzureOpenOutboundNetworkSecurityGroupRule See https://github.com/liamg/tfsec#included-checks for check info -const AzureOpenOutboundNetworkSecurityGroupRule scanner.CheckCode = "AZU002" +const AzureOpenOutboundNetworkSecurityGroupRule scanner.RuleID = "AZU002" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/azurerm_unencrypted_data_lake_store.go b/internal/app/tfsec/checks/azurerm_unencrypted_data_lake_store.go index 9b7e49c6cb..ad0d1793d6 100644 --- a/internal/app/tfsec/checks/azurerm_unencrypted_data_lake_store.go +++ b/internal/app/tfsec/checks/azurerm_unencrypted_data_lake_store.go @@ -10,7 +10,7 @@ import ( ) // AzureUnencryptedDataLakeStore See https://github.com/liamg/tfsec#included-checks for check info -const AzureUnencryptedDataLakeStore scanner.CheckCode = "AZU004" +const AzureUnencryptedDataLakeStore scanner.RuleID = "AZU004" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/azurerm_unencrypted_managed_disk.go b/internal/app/tfsec/checks/azurerm_unencrypted_managed_disk.go index f0dc38290a..8df5651bbd 100644 --- a/internal/app/tfsec/checks/azurerm_unencrypted_managed_disk.go +++ b/internal/app/tfsec/checks/azurerm_unencrypted_managed_disk.go @@ -11,7 +11,7 @@ import ( ) // AzureUnencryptedManagedDisk See https://github.com/liamg/tfsec#included-checks for check info -const AzureUnencryptedManagedDisk scanner.CheckCode = "AZU003" +const AzureUnencryptedManagedDisk scanner.RuleID = "AZU003" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/azurerm_virtual_machine_with_password_authentication.go b/internal/app/tfsec/checks/azurerm_virtual_machine_with_password_authentication.go index 15e4f2b0fb..45c7df39bf 100644 --- a/internal/app/tfsec/checks/azurerm_virtual_machine_with_password_authentication.go +++ b/internal/app/tfsec/checks/azurerm_virtual_machine_with_password_authentication.go @@ -11,7 +11,7 @@ import ( ) // AzureVMWithPasswordAuthentication See https://github.com/liamg/tfsec#included-checks for check info -const AzureVMWithPasswordAuthentication scanner.CheckCode = "AZU005" +const AzureVMWithPasswordAuthentication scanner.RuleID = "AZU005" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/generic_sensitive_attributes.go b/internal/app/tfsec/checks/generic_sensitive_attributes.go index 8288071fbb..e1eba80f31 100644 --- a/internal/app/tfsec/checks/generic_sensitive_attributes.go +++ b/internal/app/tfsec/checks/generic_sensitive_attributes.go @@ -12,7 +12,7 @@ import ( ) // GenericSensitiveAttributes See https://github.com/liamg/tfsec#included-checks for check info -const GenericSensitiveAttributes scanner.CheckCode = "GEN003" +const GenericSensitiveAttributes scanner.RuleID = "GEN003" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/generic_sensitive_locals.go b/internal/app/tfsec/checks/generic_sensitive_locals.go index d6244ec039..e5987f818c 100644 --- a/internal/app/tfsec/checks/generic_sensitive_locals.go +++ b/internal/app/tfsec/checks/generic_sensitive_locals.go @@ -12,7 +12,7 @@ import ( ) // GenericSensitiveLocals See https://github.com/liamg/tfsec#included-checks for check info -const GenericSensitiveLocals scanner.CheckCode = "GEN002" +const GenericSensitiveLocals scanner.RuleID = "GEN002" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/generic_sensitive_variables.go b/internal/app/tfsec/checks/generic_sensitive_variables.go index ebdc3837bf..27c84cf187 100644 --- a/internal/app/tfsec/checks/generic_sensitive_variables.go +++ b/internal/app/tfsec/checks/generic_sensitive_variables.go @@ -12,7 +12,7 @@ import ( ) // GenericSensitiveVariables See https://github.com/liamg/tfsec#included-checks for check info -const GenericSensitiveVariables scanner.CheckCode = "GEN001" +const GenericSensitiveVariables scanner.RuleID = "GEN001" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/gke_abac_enabled.go b/internal/app/tfsec/checks/gke_abac_enabled.go index 85b0bf3ba5..800b007757 100644 --- a/internal/app/tfsec/checks/gke_abac_enabled.go +++ b/internal/app/tfsec/checks/gke_abac_enabled.go @@ -8,7 +8,7 @@ import ( ) // GkeAbacEnabled See https://github.com/liamg/tfsec#included-checks for check info -const GkeAbacEnabled scanner.CheckCode = "GCP005" +const GkeAbacEnabled scanner.RuleID = "GCP005" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/google_open_firewall_rules.go b/internal/app/tfsec/checks/google_open_firewall_rules.go index f187e496a6..17f5b9ba94 100644 --- a/internal/app/tfsec/checks/google_open_firewall_rules.go +++ b/internal/app/tfsec/checks/google_open_firewall_rules.go @@ -10,10 +10,10 @@ import ( ) // GoogleOpenInboundFirewallRule See https://github.com/liamg/tfsec#included-checks for check info -const GoogleOpenInboundFirewallRule scanner.CheckCode = "GCP003" +const GoogleOpenInboundFirewallRule scanner.RuleID = "GCP003" // GoogleOpenOutboundFirewallRule See https://github.com/liamg/tfsec#included-checks for check info -const GoogleOpenOutboundFirewallRule scanner.CheckCode = "GCP004" +const GoogleOpenOutboundFirewallRule scanner.RuleID = "GCP004" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/google_unencrypted_disk.go b/internal/app/tfsec/checks/google_unencrypted_disk.go index 321876f4f8..697ee990dc 100644 --- a/internal/app/tfsec/checks/google_unencrypted_disk.go +++ b/internal/app/tfsec/checks/google_unencrypted_disk.go @@ -8,7 +8,7 @@ import ( ) // GoogleUnencryptedDisk See https://github.com/liamg/tfsec#included-checks for check info -const GoogleUnencryptedDisk scanner.CheckCode = "GCP001" +const GoogleUnencryptedDisk scanner.RuleID = "GCP001" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/checks/google_unencrypted_storage_bucket.go b/internal/app/tfsec/checks/google_unencrypted_storage_bucket.go index c683a66c29..c43d7469f5 100644 --- a/internal/app/tfsec/checks/google_unencrypted_storage_bucket.go +++ b/internal/app/tfsec/checks/google_unencrypted_storage_bucket.go @@ -10,7 +10,7 @@ import ( ) // GoogleUnencryptedStorageBucket See https://github.com/liamg/tfsec#included-checks for check info -const GoogleUnencryptedStorageBucket scanner.CheckCode = "GCP002" +const GoogleUnencryptedStorageBucket scanner.RuleID = "GCP002" func init() { scanner.RegisterCheck(scanner.Check{ diff --git a/internal/app/tfsec/formatters/checkstyle.go b/internal/app/tfsec/formatters/checkstyle.go index 36175bdeea..517916b7e8 100644 --- a/internal/app/tfsec/formatters/checkstyle.go +++ b/internal/app/tfsec/formatters/checkstyle.go @@ -36,10 +36,11 @@ func FormatCheckStyle(results []scanner.Result) error { fileResults := append( files[result.Range.Filename], checkstyleResult{ - Rule: string(result.Code), + Rule: string(result.RuleID), Line: result.Range.StartLine, Severity: "warn", Message: result.Description, + Link: result.Link, }, ) files[result.Range.Filename] = fileResults diff --git a/internal/app/tfsec/formatters/csv.go b/internal/app/tfsec/formatters/csv.go index 9b12f9b2b2..a9600e84dc 100644 --- a/internal/app/tfsec/formatters/csv.go +++ b/internal/app/tfsec/formatters/csv.go @@ -12,7 +12,7 @@ import ( func FormatCSV(results []scanner.Result) error { records := [][]string{ - {"file", "start_line", "end_line", "code", "description"}, + {"file", "start_line", "end_line", "rule_id", "description", "link"}, } for _, result := range results { @@ -20,8 +20,9 @@ func FormatCSV(results []scanner.Result) error { result.Range.Filename, strconv.Itoa(result.Range.StartLine), strconv.Itoa(result.Range.EndLine), - string(result.Code), + string(result.RuleID), result.Description, + result.Link, }) } diff --git a/internal/app/tfsec/formatters/default.go b/internal/app/tfsec/formatters/default.go index d3eab26243..7f8aec6e98 100644 --- a/internal/app/tfsec/formatters/default.go +++ b/internal/app/tfsec/formatters/default.go @@ -23,8 +23,9 @@ func FormatDefault(results []scanner.Result) error { [%s] %s %s -`, result.Code, result.Description, result.Range.String()) +`, result.RuleID, result.Description, result.Range.String()) highlightCode(result) + tml.Printf(" See %s for more information.\n\n", result.Link) } return nil diff --git a/internal/app/tfsec/generic_sensitive_attributes_test.go b/internal/app/tfsec/generic_sensitive_attributes_test.go index eb693f7179..1b3be8a9f0 100644 --- a/internal/app/tfsec/generic_sensitive_attributes_test.go +++ b/internal/app/tfsec/generic_sensitive_attributes_test.go @@ -13,8 +13,8 @@ func Test_AWSSensitiveAttributes(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check sensitive attribute", diff --git a/internal/app/tfsec/generic_sensitive_locals_test.go b/internal/app/tfsec/generic_sensitive_locals_test.go index 5df960fb5b..069dfa7f14 100644 --- a/internal/app/tfsec/generic_sensitive_locals_test.go +++ b/internal/app/tfsec/generic_sensitive_locals_test.go @@ -13,8 +13,8 @@ func Test_AWSSensitiveLocals(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check sensitive local with value", diff --git a/internal/app/tfsec/generic_sensitive_variables_test.go b/internal/app/tfsec/generic_sensitive_variables_test.go index 4f0a84128b..48c8205c40 100644 --- a/internal/app/tfsec/generic_sensitive_variables_test.go +++ b/internal/app/tfsec/generic_sensitive_variables_test.go @@ -13,8 +13,8 @@ func Test_AWSSensitiveVariables(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check sensitive variable with value", diff --git a/internal/app/tfsec/gke_abac_enabled_test.go b/internal/app/tfsec/gke_abac_enabled_test.go index 0a2d14d289..f7a0eb9277 100644 --- a/internal/app/tfsec/gke_abac_enabled_test.go +++ b/internal/app/tfsec/gke_abac_enabled_test.go @@ -13,8 +13,8 @@ func Test_GkeAbacEnabled(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check google_container_cluster with enable_legacy_abac set to true", diff --git a/internal/app/tfsec/google_open_firewall_rule_test.go b/internal/app/tfsec/google_open_firewall_rule_test.go index 19f860e71f..b6d1a9672a 100644 --- a/internal/app/tfsec/google_open_firewall_rule_test.go +++ b/internal/app/tfsec/google_open_firewall_rule_test.go @@ -13,8 +13,8 @@ func Test_GoogleOpenInboundFirewallRule(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check google_compute_firewall ingress on 0.0.0.0/0", @@ -48,8 +48,8 @@ func Test_GoogleOpenOutboundFirewallRule(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check google_compute_firewall egress on 0.0.0.0/0", diff --git a/internal/app/tfsec/google_unencrypted_disk_test.go b/internal/app/tfsec/google_unencrypted_disk_test.go index fe74ff8990..6a8353a276 100644 --- a/internal/app/tfsec/google_unencrypted_disk_test.go +++ b/internal/app/tfsec/google_unencrypted_disk_test.go @@ -13,8 +13,8 @@ func Test_GoogleUnencryptedDisk(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check google_compute_disk with no disk_encryption_key block", diff --git a/internal/app/tfsec/google_unencrypted_storage_bucket_test.go b/internal/app/tfsec/google_unencrypted_storage_bucket_test.go index 6dc442309b..f4f5ee9475 100644 --- a/internal/app/tfsec/google_unencrypted_storage_bucket_test.go +++ b/internal/app/tfsec/google_unencrypted_storage_bucket_test.go @@ -13,8 +13,8 @@ func Test_GoogleUnencryptedStorageBucket(t *testing.T) { var tests = []struct { name string source string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check google_storage_bucket with no encryption block", diff --git a/internal/app/tfsec/ignore_test.go b/internal/app/tfsec/ignore_test.go index 90866ed001..d632134c51 100644 --- a/internal/app/tfsec/ignore_test.go +++ b/internal/app/tfsec/ignore_test.go @@ -49,6 +49,6 @@ func Test_IgnoreSpecific(t *testing.T) { resource "bad" "my-bad" {} //tfsec:ignore:ABC123 `) require.Len(t, results, 1) - assert.Equal(t, results[0].Code, scanner.CheckCode("DEF456")) + assert.Equal(t, results[0].RuleID, scanner.RuleID("DEF456")) } diff --git a/internal/app/tfsec/module_scan_test.go b/internal/app/tfsec/module_scan_test.go index 99c6cf61fa..0e258e6f83 100644 --- a/internal/app/tfsec/module_scan_test.go +++ b/internal/app/tfsec/module_scan_test.go @@ -13,8 +13,8 @@ func Test_ProblemInModule(t *testing.T) { name string source string moduleSource string - mustIncludeResultCode scanner.CheckCode - mustExcludeResultCode scanner.CheckCode + mustIncludeResultCode scanner.RuleID + mustExcludeResultCode scanner.RuleID }{ { name: "check problem in module", diff --git a/internal/app/tfsec/scanner/check.go b/internal/app/tfsec/scanner/check.go index 246eb66196..10f34caac9 100644 --- a/internal/app/tfsec/scanner/check.go +++ b/internal/app/tfsec/scanner/check.go @@ -8,13 +8,13 @@ import ( "github.com/liamg/tfsec/internal/app/tfsec/parser" ) -// CheckCode is a unique identifier for a check -type CheckCode string +// RuleID is a unique identifier for a check +type RuleID string // Check is a targeted security test which can be applied to terraform templates. It includes the types to run on e.g. // "resource", and the labels to run on e.g. "aws_s3_bucket". type Check struct { - Code CheckCode + Code RuleID RequiredTypes []string RequiredLabels []string CheckFunc func(*Check, *parser.Block, *Context) []Result @@ -70,7 +70,7 @@ func (check *Check) IsRequiredForBlock(block *parser.Block) bool { // NewResult creates a new Result, containing the given description and range func (check *Check) NewResult(description string, r parser.Range) Result { return Result{ - Code: check.Code, + RuleID: check.Code, Description: description, Range: r, } @@ -101,7 +101,7 @@ func (check *Check) NewResultWithValueAnnotation(description string, r parser.Ra } return Result{ - Code: check.Code, + RuleID: check.Code, Description: description, Range: r, RangeAnnotation: fmt.Sprintf("[%s] %#v", typeStr, raw), diff --git a/internal/app/tfsec/scanner/result.go b/internal/app/tfsec/scanner/result.go index 148d83ea54..e1237e9f50 100644 --- a/internal/app/tfsec/scanner/result.go +++ b/internal/app/tfsec/scanner/result.go @@ -7,7 +7,8 @@ import ( // Result is a positive result for a security check. It encapsulates a code unique to the specific check it was raised // by, a human-readable description and a range type Result struct { - Code CheckCode `json:"code"` + RuleID RuleID `json:"rule_id"` + Link string `json:"link"` Range parser.Range `json:"location"` Description string `json:"description"` RangeAnnotation string `json:"-"` diff --git a/internal/app/tfsec/scanner/scanner.go b/internal/app/tfsec/scanner/scanner.go index f64eb40ee3..c1891e0708 100644 --- a/internal/app/tfsec/scanner/scanner.go +++ b/internal/app/tfsec/scanner/scanner.go @@ -25,7 +25,8 @@ func (scanner *Scanner) Scan(blocks []*parser.Block) []Result { for _, check := range GetRegisteredChecks() { if check.IsRequiredForBlock(block) { for _, result := range check.Run(block, context) { - if !scanner.checkRangeIgnored(result.Code, result.Range) { + if !scanner.checkRangeIgnored(result.RuleID, result.Range) { + result.Link = fmt.Sprintf("https://github.com/liamg/tfsec/wiki/%s", result.RuleID) results = append(results, result) } } @@ -35,7 +36,7 @@ func (scanner *Scanner) Scan(blocks []*parser.Block) []Result { return results } -func (scanner *Scanner) checkRangeIgnored(code CheckCode, r parser.Range) bool { +func (scanner *Scanner) checkRangeIgnored(code RuleID, r parser.Range) bool { raw, err := ioutil.ReadFile(r.Filename) if err != nil { return false diff --git a/internal/app/tfsec/setup_test.go b/internal/app/tfsec/setup_test.go index 7df1b337ce..20a1ae06c6 100644 --- a/internal/app/tfsec/setup_test.go +++ b/internal/app/tfsec/setup_test.go @@ -13,7 +13,7 @@ import ( "github.com/liamg/tfsec/internal/app/tfsec/scanner" ) -const exampleCheckCode scanner.CheckCode = "EXA001" +const exampleCheckCode scanner.RuleID = "EXA001" func TestMain(t *testing.M) { @@ -56,22 +56,22 @@ func createTestFile(filename, contents string) string { return path } -func assertCheckCode(t *testing.T, includeCode scanner.CheckCode, excludeCode scanner.CheckCode, results []scanner.Result) { +func assertCheckCode(t *testing.T, includeCode scanner.RuleID, excludeCode scanner.RuleID, results []scanner.Result) { var foundInclude bool var foundExclude bool for _, result := range results { - if result.Code == excludeCode { + if result.RuleID == excludeCode { foundExclude = true } - if result.Code == includeCode { + if result.RuleID == includeCode { foundInclude = true } } assert.False(t, foundExclude, fmt.Sprintf("result with code '%s' was found but should not have been", excludeCode)) - if includeCode != scanner.CheckCode("") { + if includeCode != scanner.RuleID("") { assert.True(t, foundInclude, fmt.Sprintf("result with code '%s' was not found but should have been", includeCode)) } } From d110462a1c78cb1f957a37549016d8854beedc51 Mon Sep 17 00:00:00 2001 From: Liam Galvin Date: Sat, 11 Jan 2020 14:44:07 +0000 Subject: [PATCH 2/3] Add severity to all rules and output formats --- internal/app/tfsec/checks/aws_acl.go | 1 + internal/app/tfsec/checks/aws_bucket_logging.go | 1 + internal/app/tfsec/checks/aws_classic.go | 1 + internal/app/tfsec/checks/aws_http.go | 1 + .../aws_missing_description_in_security_group.go | 2 ++ internal/app/tfsec/checks/aws_not_internal.go | 2 ++ .../checks/aws_open_security_group_rules.go | 2 ++ .../app/tfsec/checks/aws_open_security_groups.go | 2 ++ internal/app/tfsec/checks/aws_outdated_ssl.go | 1 + internal/app/tfsec/checks/aws_public.go | 1 + internal/app/tfsec/checks/aws_public_ip.go | 1 + ...ws_task_definition_includes_sensitive_data.go | 1 + .../tfsec/checks/aws_unencrypted_block_device.go | 5 +++++ .../tfsec/checks/aws_unencrypted_s3_bucket.go | 4 ++++ .../tfsec/checks/aws_unencrypted_sns_topic.go | 2 ++ .../tfsec/checks/aws_unencrypted_sqs_queue.go | 2 ++ .../azurerm_open_network_security_rules.go | 4 ++++ .../azurerm_unencrypted_data_lake_store.go | 1 + .../checks/azurerm_unencrypted_managed_disk.go | 2 ++ ...rtual_machine_with_password_authentication.go | 1 + .../tfsec/checks/generic_sensitive_attributes.go | 1 + .../app/tfsec/checks/generic_sensitive_locals.go | 1 + .../tfsec/checks/generic_sensitive_variables.go | 1 + internal/app/tfsec/checks/gke_abac_enabled.go | 1 + .../tfsec/checks/google_open_firewall_rules.go | 2 ++ .../app/tfsec/checks/google_unencrypted_disk.go | 2 ++ .../checks/google_unencrypted_storage_bucket.go | 3 +++ internal/app/tfsec/formatters/checkstyle.go | 2 +- internal/app/tfsec/formatters/csv.go | 3 ++- internal/app/tfsec/formatters/default.go | 16 ++++++++++++++-- internal/app/tfsec/scanner/check.go | 9 +++++---- internal/app/tfsec/scanner/result.go | 9 +++++++++ 32 files changed, 79 insertions(+), 8 deletions(-) diff --git a/internal/app/tfsec/checks/aws_acl.go b/internal/app/tfsec/checks/aws_acl.go index 37cd0b0818..f93a631485 100644 --- a/internal/app/tfsec/checks/aws_acl.go +++ b/internal/app/tfsec/checks/aws_acl.go @@ -27,6 +27,7 @@ func init() { fmt.Sprintf("Resource '%s' has an ACL which allows public read access.", block.Name()), attr.Range(), attr, + scanner.SeverityWarning, ), } } diff --git a/internal/app/tfsec/checks/aws_bucket_logging.go b/internal/app/tfsec/checks/aws_bucket_logging.go index 6fa681a73f..c272e0b96a 100644 --- a/internal/app/tfsec/checks/aws_bucket_logging.go +++ b/internal/app/tfsec/checks/aws_bucket_logging.go @@ -22,6 +22,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' does not have logging enabled.", block.Name()), block.Range(), + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/checks/aws_classic.go b/internal/app/tfsec/checks/aws_classic.go index 392e493954..d313aa9b27 100644 --- a/internal/app/tfsec/checks/aws_classic.go +++ b/internal/app/tfsec/checks/aws_classic.go @@ -21,6 +21,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' uses EC2 Classic. Use a VPC instead.", block.Name()), block.Range(), + scanner.SeverityError, ), } }, diff --git a/internal/app/tfsec/checks/aws_http.go b/internal/app/tfsec/checks/aws_http.go index c4c3b3db1c..60723194b7 100644 --- a/internal/app/tfsec/checks/aws_http.go +++ b/internal/app/tfsec/checks/aws_http.go @@ -40,6 +40,7 @@ func init() { fmt.Sprintf("Resource '%s' uses plain HTTP instead of HTTPS.", block.Name()), reportRange, protocolAttr, + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/checks/aws_missing_description_in_security_group.go b/internal/app/tfsec/checks/aws_missing_description_in_security_group.go index f7e1e3b41e..140ce10091 100644 --- a/internal/app/tfsec/checks/aws_missing_description_in_security_group.go +++ b/internal/app/tfsec/checks/aws_missing_description_in_security_group.go @@ -25,6 +25,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' should include a description for auditing purposes.", block.Name()), block.Range(), + scanner.SeverityError, ), } } @@ -35,6 +36,7 @@ func init() { fmt.Sprintf("Resource '%s' should include a non-empty description for auditing purposes.", block.Name()), descriptionAttr.Range(), descriptionAttr, + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/checks/aws_not_internal.go b/internal/app/tfsec/checks/aws_not_internal.go index 755549f9a3..e14605306a 100644 --- a/internal/app/tfsec/checks/aws_not_internal.go +++ b/internal/app/tfsec/checks/aws_not_internal.go @@ -24,6 +24,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' is exposed publicly.", block.Name()), block.Range(), + scanner.SeverityWarning, ), } } else if internalAttr.Type() == cty.Bool && internalAttr.Value().False() { @@ -32,6 +33,7 @@ func init() { fmt.Sprintf("Resource '%s' is exposed publicly.", block.Name()), internalAttr.Range(), internalAttr, + scanner.SeverityWarning, ), } } diff --git a/internal/app/tfsec/checks/aws_open_security_group_rules.go b/internal/app/tfsec/checks/aws_open_security_group_rules.go index 7ab61297d1..fd5c0814e3 100644 --- a/internal/app/tfsec/checks/aws_open_security_group_rules.go +++ b/internal/app/tfsec/checks/aws_open_security_group_rules.go @@ -45,6 +45,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines a fully open ingress security group rule.", block.Name()), cidrBlocksAttr.Range(), + scanner.SeverityWarning, ), } } @@ -84,6 +85,7 @@ func init() { fmt.Sprintf("Resource '%s' defines a fully open egress security group rule.", block.Name()), cidrBlocksAttr.Range(), cidrBlocksAttr, + scanner.SeverityWarning, ), } } diff --git a/internal/app/tfsec/checks/aws_open_security_groups.go b/internal/app/tfsec/checks/aws_open_security_groups.go index cdf640a401..11f59321f7 100644 --- a/internal/app/tfsec/checks/aws_open_security_groups.go +++ b/internal/app/tfsec/checks/aws_open_security_groups.go @@ -37,6 +37,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines a fully open ingress security group.", block.Name()), cidrBlocksAttr.Range(), + scanner.SeverityWarning, ), ) } @@ -70,6 +71,7 @@ func init() { fmt.Sprintf("Resource '%s' defines a fully open egress security group.", block.Name()), cidrBlocksAttr.Range(), cidrBlocksAttr, + scanner.SeverityWarning, ), ) } diff --git a/internal/app/tfsec/checks/aws_outdated_ssl.go b/internal/app/tfsec/checks/aws_outdated_ssl.go index 25f9426417..de2e27b055 100644 --- a/internal/app/tfsec/checks/aws_outdated_ssl.go +++ b/internal/app/tfsec/checks/aws_outdated_ssl.go @@ -35,6 +35,7 @@ func init() { fmt.Sprintf("Resource '%s' is using an outdated SSL policy.", block.Name()), sslPolicyAttr.Range(), sslPolicyAttr, + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/checks/aws_public.go b/internal/app/tfsec/checks/aws_public.go index 149d9b6a28..349b6d7212 100644 --- a/internal/app/tfsec/checks/aws_public.go +++ b/internal/app/tfsec/checks/aws_public.go @@ -27,6 +27,7 @@ func init() { fmt.Sprintf("Resource '%s' is exposed publicly.", block.Name()), publicAttr.Range(), publicAttr, + scanner.SeverityWarning, ), } } diff --git a/internal/app/tfsec/checks/aws_public_ip.go b/internal/app/tfsec/checks/aws_public_ip.go index 1d58e12dd7..e30ec56d50 100644 --- a/internal/app/tfsec/checks/aws_public_ip.go +++ b/internal/app/tfsec/checks/aws_public_ip.go @@ -27,6 +27,7 @@ func init() { fmt.Sprintf("Resource '%s' has a public IP address associated.", block.Name()), publicAttr.Range(), publicAttr, + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/checks/aws_task_definition_includes_sensitive_data.go b/internal/app/tfsec/checks/aws_task_definition_includes_sensitive_data.go index 8197597f18..7a7a7374c5 100644 --- a/internal/app/tfsec/checks/aws_task_definition_includes_sensitive_data.go +++ b/internal/app/tfsec/checks/aws_task_definition_includes_sensitive_data.go @@ -46,6 +46,7 @@ func init() { fmt.Sprintf("Resource '%s' includes a potentially sensitive environment variable '%s' in the container definition.", block.Name(), env.Name), definitionsAttr.Range(), definitionsAttr, + scanner.SeverityWarning, )) } } diff --git a/internal/app/tfsec/checks/aws_unencrypted_block_device.go b/internal/app/tfsec/checks/aws_unencrypted_block_device.go index 52410bda63..8a7254e535 100644 --- a/internal/app/tfsec/checks/aws_unencrypted_block_device.go +++ b/internal/app/tfsec/checks/aws_unencrypted_block_device.go @@ -37,6 +37,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' uses an unencrypted root EBS block device. Consider adding root_block_device{ encrypted = true }", block.Name()), block.Range(), + scanner.SeverityError, ), ) } else if rootDeviceBlock != nil { @@ -46,6 +47,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' uses an unencrypted root EBS block device. Consider adding encrypted = true", block.Name()), rootDeviceBlock.Range(), + scanner.SeverityError, ), ) } else if encryptedAttr != nil && encryptedAttr.Type() == cty.Bool && encryptedAttr.Value().False() { @@ -54,6 +56,7 @@ func init() { fmt.Sprintf("Resource '%s' uses an unencrypted root EBS block device.", block.Name()), encryptedAttr.Range(), encryptedAttr, + scanner.SeverityError, ), ) } @@ -67,6 +70,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' uses an unencrypted EBS block device. Consider adding encrypted = true", block.Name()), ebsDeviceBlock.Range(), + scanner.SeverityError, ), ) } else if encryptedAttr != nil && encryptedAttr.Type() == cty.Bool && encryptedAttr.Value().False() { @@ -75,6 +79,7 @@ func init() { fmt.Sprintf("Resource '%s' uses an unencrypted EBS block device.", block.Name()), encryptedAttr.Range(), encryptedAttr, + scanner.SeverityError, ), ) } diff --git a/internal/app/tfsec/checks/aws_unencrypted_s3_bucket.go b/internal/app/tfsec/checks/aws_unencrypted_s3_bucket.go index 67ec8a0f37..97eac31f0e 100644 --- a/internal/app/tfsec/checks/aws_unencrypted_s3_bucket.go +++ b/internal/app/tfsec/checks/aws_unencrypted_s3_bucket.go @@ -24,6 +24,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines an unencrypted S3 bucket (missing server_side_encryption_configuration block).", block.Name()), block.Range(), + scanner.SeverityError, ), } } @@ -34,6 +35,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines an unencrypted S3 bucket (missing rule block).", block.Name()), encryptionBlock.Range(), + scanner.SeverityError, ), } } @@ -44,6 +46,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines an unencrypted S3 bucket (missing apply_server_side_encryption_by_default block).", block.Name()), ruleBlock.Range(), + scanner.SeverityError, ), } } @@ -53,6 +56,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines an unencrypted S3 bucket (missing sse_algorithm attribute).", block.Name()), applyBlock.Range(), + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/checks/aws_unencrypted_sns_topic.go b/internal/app/tfsec/checks/aws_unencrypted_sns_topic.go index 24d0af0730..305cfffaca 100644 --- a/internal/app/tfsec/checks/aws_unencrypted_sns_topic.go +++ b/internal/app/tfsec/checks/aws_unencrypted_sns_topic.go @@ -26,6 +26,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines an unencrypted SNS topic.", block.Name()), block.Range(), + scanner.SeverityError, ), } } else if kmsKeyIDAttr.Type() == cty.String && kmsKeyIDAttr.Value().AsString() == "" { @@ -34,6 +35,7 @@ func init() { fmt.Sprintf("Resource '%s' defines an unencrypted SNS topic.", block.Name()), kmsKeyIDAttr.Range(), kmsKeyIDAttr, + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/checks/aws_unencrypted_sqs_queue.go b/internal/app/tfsec/checks/aws_unencrypted_sqs_queue.go index a38d140c45..edc367d2d2 100644 --- a/internal/app/tfsec/checks/aws_unencrypted_sqs_queue.go +++ b/internal/app/tfsec/checks/aws_unencrypted_sqs_queue.go @@ -26,6 +26,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines an unencrypted SQS queue.", block.Name()), block.Range(), + scanner.SeverityError, ), } } else if kmsKeyIDAttr.Type() == cty.String && kmsKeyIDAttr.Value().AsString() == "" { @@ -34,6 +35,7 @@ func init() { fmt.Sprintf("Resource '%s' defines an unencrypted SQS queue.", block.Name()), kmsKeyIDAttr.Range(), kmsKeyIDAttr, + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/checks/azurerm_open_network_security_rules.go b/internal/app/tfsec/checks/azurerm_open_network_security_rules.go index cb65e76283..a1f06345e0 100644 --- a/internal/app/tfsec/checks/azurerm_open_network_security_rules.go +++ b/internal/app/tfsec/checks/azurerm_open_network_security_rules.go @@ -40,6 +40,7 @@ func init() { ), prefixAttr.Range(), prefixAttr, + scanner.SeverityWarning, ), } } @@ -55,6 +56,7 @@ func init() { fmt.Sprintf("Resource '%s' defines a fully open %s security group rule.", block.Name(), prefix.AsString()), prefixesAttr.Range(), prefixesAttr, + scanner.SeverityWarning, ), ) } @@ -88,6 +90,7 @@ func init() { ), prefixAttr.Range(), prefixAttr, + scanner.SeverityWarning, ), } } @@ -103,6 +106,7 @@ func init() { fmt.Sprintf("Resource '%s' defines a fully open %s security group rule.", block.Name(), prefix.AsString()), prefixesAttr.Range(), prefixesAttr, + scanner.SeverityWarning, ), ) } diff --git a/internal/app/tfsec/checks/azurerm_unencrypted_data_lake_store.go b/internal/app/tfsec/checks/azurerm_unencrypted_data_lake_store.go index ad0d1793d6..e345b0840a 100644 --- a/internal/app/tfsec/checks/azurerm_unencrypted_data_lake_store.go +++ b/internal/app/tfsec/checks/azurerm_unencrypted_data_lake_store.go @@ -29,6 +29,7 @@ func init() { ), encryptionStateAttr.Range(), encryptionStateAttr, + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/checks/azurerm_unencrypted_managed_disk.go b/internal/app/tfsec/checks/azurerm_unencrypted_managed_disk.go index 8df5651bbd..6ecb072e51 100644 --- a/internal/app/tfsec/checks/azurerm_unencrypted_managed_disk.go +++ b/internal/app/tfsec/checks/azurerm_unencrypted_managed_disk.go @@ -29,6 +29,7 @@ func init() { block.Name(), ), block.Range(), + scanner.SeverityError, ), } } @@ -43,6 +44,7 @@ func init() { ), enabledAttr.Range(), enabledAttr, + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/checks/azurerm_virtual_machine_with_password_authentication.go b/internal/app/tfsec/checks/azurerm_virtual_machine_with_password_authentication.go index 45c7df39bf..54d62a9c4e 100644 --- a/internal/app/tfsec/checks/azurerm_virtual_machine_with_password_authentication.go +++ b/internal/app/tfsec/checks/azurerm_virtual_machine_with_password_authentication.go @@ -31,6 +31,7 @@ func init() { ), passwordAuthDisabledAttr.Range(), passwordAuthDisabledAttr, + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/checks/generic_sensitive_attributes.go b/internal/app/tfsec/checks/generic_sensitive_attributes.go index e1eba80f31..8d931c2142 100644 --- a/internal/app/tfsec/checks/generic_sensitive_attributes.go +++ b/internal/app/tfsec/checks/generic_sensitive_attributes.go @@ -31,6 +31,7 @@ func init() { fmt.Sprintf("Block '%s' includes a potentially sensitive attribute which is defined within the project.", block.Name()), attribute.Range(), attribute, + scanner.SeverityWarning, )) } diff --git a/internal/app/tfsec/checks/generic_sensitive_locals.go b/internal/app/tfsec/checks/generic_sensitive_locals.go index e5987f818c..cd3b2a99d7 100644 --- a/internal/app/tfsec/checks/generic_sensitive_locals.go +++ b/internal/app/tfsec/checks/generic_sensitive_locals.go @@ -29,6 +29,7 @@ func init() { fmt.Sprintf("Local '%s' includes a potentially sensitive value which is defined within the project.", block.Name()), attribute.Range(), attribute, + scanner.SeverityWarning, )) } } diff --git a/internal/app/tfsec/checks/generic_sensitive_variables.go b/internal/app/tfsec/checks/generic_sensitive_variables.go index 27c84cf187..8b73db3788 100644 --- a/internal/app/tfsec/checks/generic_sensitive_variables.go +++ b/internal/app/tfsec/checks/generic_sensitive_variables.go @@ -41,6 +41,7 @@ func init() { fmt.Sprintf("Variable '%s' includes a potentially sensitive default value.", block.Name()), attribute.Range(), attribute, + scanner.SeverityWarning, )) } } diff --git a/internal/app/tfsec/checks/gke_abac_enabled.go b/internal/app/tfsec/checks/gke_abac_enabled.go index 800b007757..d5c140c967 100644 --- a/internal/app/tfsec/checks/gke_abac_enabled.go +++ b/internal/app/tfsec/checks/gke_abac_enabled.go @@ -23,6 +23,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines a cluster with ABAC enabled. Disable and rely on RBAC instead. https://cloud.google.com/kubernetes-engine/docs/how-to/hardening-your-cluster#leave_abac_disabled_default_for_110", block.Name()), block.Range(), + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/checks/google_open_firewall_rules.go b/internal/app/tfsec/checks/google_open_firewall_rules.go index 17f5b9ba94..34459982c6 100644 --- a/internal/app/tfsec/checks/google_open_firewall_rules.go +++ b/internal/app/tfsec/checks/google_open_firewall_rules.go @@ -34,6 +34,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines a fully open inbound firewall rule.", block.Name()), sourceRanges.Range(), + scanner.SeverityWarning, ), } } @@ -63,6 +64,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines a fully open outbound firewall rule.", block.Name()), destinationRanges.Range(), + scanner.SeverityWarning, ), } } diff --git a/internal/app/tfsec/checks/google_unencrypted_disk.go b/internal/app/tfsec/checks/google_unencrypted_disk.go index 697ee990dc..70f4fd056e 100644 --- a/internal/app/tfsec/checks/google_unencrypted_disk.go +++ b/internal/app/tfsec/checks/google_unencrypted_disk.go @@ -23,6 +23,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines an unencrypted disk.", block.Name()), block.Range(), + scanner.SeverityError, ), } } @@ -32,6 +33,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines an unencrypted disk. You should specify raw_key or kms_key_self_link.", block.Name()), keyBlock.Range(), + scanner.SeverityError, ), } diff --git a/internal/app/tfsec/checks/google_unencrypted_storage_bucket.go b/internal/app/tfsec/checks/google_unencrypted_storage_bucket.go index c43d7469f5..1684fb2931 100644 --- a/internal/app/tfsec/checks/google_unencrypted_storage_bucket.go +++ b/internal/app/tfsec/checks/google_unencrypted_storage_bucket.go @@ -25,6 +25,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines an unencrypted storage bucket.", block.Name()), block.Range(), + scanner.SeverityError, ), } } @@ -34,6 +35,7 @@ func init() { check.NewResult( fmt.Sprintf("Resource '%s' defines an unencrypted storage bucket. You should specify default_kms_key_name to enable encryption.", block.Name()), encryptionBlock.Range(), + scanner.SeverityError, ), } } else if kmsAttr.Type() != cty.String || kmsAttr.Value().AsString() == "" { @@ -42,6 +44,7 @@ func init() { fmt.Sprintf("Resource '%s' defines an unencrypted storage bucket. The specified default_kms_key_name is empty.", block.Name()), kmsAttr.Range(), kmsAttr, + scanner.SeverityError, ), } } diff --git a/internal/app/tfsec/formatters/checkstyle.go b/internal/app/tfsec/formatters/checkstyle.go index 517916b7e8..e185e01a83 100644 --- a/internal/app/tfsec/formatters/checkstyle.go +++ b/internal/app/tfsec/formatters/checkstyle.go @@ -38,7 +38,7 @@ func FormatCheckStyle(results []scanner.Result) error { checkstyleResult{ Rule: string(result.RuleID), Line: result.Range.StartLine, - Severity: "warn", + Severity: string(result.Severity), Message: result.Description, Link: result.Link, }, diff --git a/internal/app/tfsec/formatters/csv.go b/internal/app/tfsec/formatters/csv.go index a9600e84dc..291872ec03 100644 --- a/internal/app/tfsec/formatters/csv.go +++ b/internal/app/tfsec/formatters/csv.go @@ -12,7 +12,7 @@ import ( func FormatCSV(results []scanner.Result) error { records := [][]string{ - {"file", "start_line", "end_line", "rule_id", "description", "link"}, + {"file", "start_line", "end_line", "rule_id", "severity", "description", "link"}, } for _, result := range results { @@ -21,6 +21,7 @@ func FormatCSV(results []scanner.Result) error { strconv.Itoa(result.Range.StartLine), strconv.Itoa(result.Range.EndLine), string(result.RuleID), + string(result.Severity), result.Description, result.Link, }) diff --git a/internal/app/tfsec/formatters/default.go b/internal/app/tfsec/formatters/default.go index 7f8aec6e98..efb576066d 100644 --- a/internal/app/tfsec/formatters/default.go +++ b/internal/app/tfsec/formatters/default.go @@ -16,14 +16,26 @@ func FormatDefault(results []scanner.Result) error { terminal.PrintSuccessf("\nNo problems detected!\n") } + var severity string + terminal.PrintErrorf("\n%d potential problems detected:\n\n", len(results)) for i, result := range results { terminal.PrintErrorf("Problem %d\n", i+1) + + switch result.Severity { + case scanner.SeverityError: + severity = tml.Sprintf("%s", result.Severity) + case scanner.SeverityWarning: + severity = tml.Sprintf("%s", result.Severity) + default: + severity = tml.Sprintf("%s", result.Severity) + } + _ = tml.Printf(` - [%s] %s + [%s][%s] %s %s -`, result.RuleID, result.Description, result.Range.String()) +`, result.RuleID, severity, result.Description, result.Range.String()) highlightCode(result) tml.Printf(" See %s for more information.\n\n", result.Link) } diff --git a/internal/app/tfsec/scanner/check.go b/internal/app/tfsec/scanner/check.go index 10f34caac9..a593e94633 100644 --- a/internal/app/tfsec/scanner/check.go +++ b/internal/app/tfsec/scanner/check.go @@ -68,18 +68,19 @@ func (check *Check) IsRequiredForBlock(block *parser.Block) bool { } // NewResult creates a new Result, containing the given description and range -func (check *Check) NewResult(description string, r parser.Range) Result { +func (check *Check) NewResult(description string, r parser.Range, severity Severity) Result { return Result{ RuleID: check.Code, Description: description, Range: r, + Severity: severity, } } -func (check *Check) NewResultWithValueAnnotation(description string, r parser.Range, attr *parser.Attribute) Result { +func (check *Check) NewResultWithValueAnnotation(description string, r parser.Range, attr *parser.Attribute, severity Severity) Result { if attr == nil || attr.IsLiteral() { - return check.NewResult(description, r) + return check.NewResult(description, r, severity) } var raw interface{} @@ -97,7 +98,7 @@ func (check *Check) NewResultWithValueAnnotation(description string, r parser.Ra raw, _ = attr.Value().AsBigFloat().Float64() typeStr = "number" default: - return check.NewResult(description, r) + return check.NewResult(description, r, severity) } return Result{ diff --git a/internal/app/tfsec/scanner/result.go b/internal/app/tfsec/scanner/result.go index e1237e9f50..c7390824ce 100644 --- a/internal/app/tfsec/scanner/result.go +++ b/internal/app/tfsec/scanner/result.go @@ -12,4 +12,13 @@ type Result struct { Range parser.Range `json:"location"` Description string `json:"description"` RangeAnnotation string `json:"-"` + Severity Severity `json:"severity"` } + +type Severity string + +const ( + SeverityError Severity = "ERROR" + SeverityWarning Severity = "WARNING" + SeverityInfo Severity = "INFO" +) From 9cc7a5b9a586923a90d858fab2e7120ea3c6a60d Mon Sep 17 00:00:00 2001 From: Liam Galvin Date: Sat, 11 Jan 2020 14:47:28 +0000 Subject: [PATCH 3/3] Fix tests --- go.mod | 2 -- internal/app/tfsec/ignore_test.go | 4 ++-- internal/app/tfsec/setup_test.go | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index c1feee113a..f211019a7f 100644 --- a/go.mod +++ b/go.mod @@ -31,8 +31,6 @@ require ( github.com/liamg/clinch v1.0.0 github.com/liamg/tml v0.2.0 github.com/mitchellh/go-wordwrap v1.0.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/pelletier/go-toml v1.6.0 // indirect github.com/prometheus/client_golang v1.2.1 // indirect diff --git a/internal/app/tfsec/ignore_test.go b/internal/app/tfsec/ignore_test.go index d632134c51..b918aedf93 100644 --- a/internal/app/tfsec/ignore_test.go +++ b/internal/app/tfsec/ignore_test.go @@ -30,7 +30,7 @@ func Test_IgnoreSpecific(t *testing.T) { RequiredLabels: []string{"bad"}, CheckFunc: func(check *scanner.Check, block *parser.Block, _ *scanner.Context) []scanner.Result { return []scanner.Result{ - check.NewResult("example problem", block.Range()), + check.NewResult("example problem", block.Range(), scanner.SeverityError), } }, }) @@ -40,7 +40,7 @@ func Test_IgnoreSpecific(t *testing.T) { RequiredLabels: []string{"bad"}, CheckFunc: func(check *scanner.Check, block *parser.Block, _ *scanner.Context) []scanner.Result { return []scanner.Result{ - check.NewResult("example problem", block.Range()), + check.NewResult("example problem", block.Range(), scanner.SeverityError), } }, }) diff --git a/internal/app/tfsec/setup_test.go b/internal/app/tfsec/setup_test.go index 20a1ae06c6..fd84fadee4 100644 --- a/internal/app/tfsec/setup_test.go +++ b/internal/app/tfsec/setup_test.go @@ -22,7 +22,7 @@ func TestMain(t *testing.M) { RequiredLabels: []string{"problem"}, CheckFunc: func(check *scanner.Check, block *parser.Block, _ *scanner.Context) []scanner.Result { return []scanner.Result{ - check.NewResult("example problem", block.Range()), + check.NewResult("example problem", block.Range(), scanner.SeverityError), } }, })