-
Notifications
You must be signed in to change notification settings - Fork 547
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rework GCP-001 (and add new raw_key check) (#846)
* Rework GCP-001 - resolves #137
- Loading branch information
Showing
4 changed files
with
139 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package rules | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/tfsec/tfsec/internal/app/tfsec/block" | ||
"github.com/tfsec/tfsec/internal/app/tfsec/hclcontext" | ||
"github.com/tfsec/tfsec/internal/app/tfsec/scanner" | ||
"github.com/tfsec/tfsec/pkg/provider" | ||
"github.com/tfsec/tfsec/pkg/result" | ||
"github.com/tfsec/tfsec/pkg/rule" | ||
"github.com/tfsec/tfsec/pkg/severity" | ||
) | ||
|
||
const GCPRawEncryptionKeySpecifiedForComputeDisk = "GCP013" | ||
const GCPRawEncryptionKeySpecifiedForComputeDiskDescription = "The encryption key used to encrypt a compute disk has been specified in plaintext." | ||
const GCPRawEncryptionKeySpecifiedForComputeDiskImpact = "The encryption key should be considered compromised as it is not stored securely." | ||
const GCPRawEncryptionKeySpecifiedForComputeDiskResolution = "Reference a managed key rather than include the key in raw format." | ||
const GCPRawEncryptionKeySpecifiedForComputeDiskExplanation = ` | ||
Sensitve values such as raw encryption keys should not be included in your Terraform code, and should be stored securely by a secrets manager. | ||
` | ||
const GCPRawEncryptionKeySpecifiedForComputeDiskBadExample = ` | ||
resource "google_compute_disk" "good_example" { | ||
disk_encryption_key { | ||
raw_key="b2ggbm8gdGhpcyBpcyBiYWQ=" | ||
} | ||
} | ||
` | ||
const GCPRawEncryptionKeySpecifiedForComputeDiskGoodExample = ` | ||
resource "google_compute_disk" "good_example" { | ||
disk_encryption_key { | ||
kms_key_self_link = google_kms_crypto_key.my_crypto_key.id | ||
} | ||
} | ||
` | ||
|
||
func init() { | ||
scanner.RegisterCheckRule(rule.Rule{ | ||
ID: GCPRawEncryptionKeySpecifiedForComputeDisk, | ||
Documentation: rule.RuleDocumentation{ | ||
Summary: GCPRawEncryptionKeySpecifiedForComputeDiskDescription, | ||
Explanation: GCPRawEncryptionKeySpecifiedForComputeDiskExplanation, | ||
Impact: GCPRawEncryptionKeySpecifiedForComputeDiskImpact, | ||
Resolution: GCPRawEncryptionKeySpecifiedForComputeDiskResolution, | ||
BadExample: GCPRawEncryptionKeySpecifiedForComputeDiskBadExample, | ||
GoodExample: GCPRawEncryptionKeySpecifiedForComputeDiskGoodExample, | ||
Links: []string{ | ||
"https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_disk#kms_key_self_link", | ||
"https://cloud.google.com/compute/docs/disks/customer-supplied-encryption", | ||
}, | ||
}, | ||
Provider: provider.GCPProvider, | ||
RequiredTypes: []string{"resource"}, | ||
RequiredLabels: []string{"google_compute_disk"}, | ||
DefaultSeverity: severity.Error, | ||
CheckFunc: func(set result.Set, resourceBlock block.Block, _ *hclcontext.Context) { | ||
|
||
keyBlock := resourceBlock.GetBlock("disk_encryption_key") | ||
if keyBlock == nil { | ||
return | ||
} | ||
|
||
rawKeyAttr := keyBlock.GetAttribute("raw_key") | ||
if rawKeyAttr == nil { | ||
return | ||
} | ||
|
||
if rawKeyAttr.IsString() { | ||
set.Add( | ||
result.New(resourceBlock). | ||
WithDescription(fmt.Sprintf("Resource '%s' specifies an encryption key in raw format.", resourceBlock.FullName())). | ||
WithRange(rawKeyAttr.Range()). | ||
WithAttributeAnnotation(rawKeyAttr). | ||
WithSeverity(severity.Error), | ||
) | ||
} | ||
|
||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/tfsec/tfsec/internal/app/tfsec/rules" | ||
) | ||
|
||
func Test_GCPRawEncryptionKeySpecifiedForComputeDisk(t *testing.T) { | ||
|
||
var tests = []struct { | ||
name string | ||
source string | ||
mustIncludeResultCode string | ||
mustExcludeResultCode string | ||
}{ | ||
{ | ||
name: "Fails with raw key supplied", | ||
source: ` | ||
resource "google_compute_disk" "good_example" { | ||
disk_encryption_key { | ||
raw_key="b2ggbm8gdGhpcyBpcyBiYWQ=" | ||
} | ||
} | ||
`, | ||
mustIncludeResultCode: rules.GCPRawEncryptionKeySpecifiedForComputeDisk, | ||
}, | ||
{ | ||
name: "Passes without raw key", | ||
source: ` | ||
resource "google_compute_disk" "good_example" { | ||
disk_encryption_key { | ||
kms_key_self_link = google_kms_crypto_key.my_crypto_key.id | ||
} | ||
} | ||
`, | ||
mustExcludeResultCode: rules.GCPRawEncryptionKeySpecifiedForComputeDisk, | ||
}, | ||
} | ||
|
||
for _, test := range tests { | ||
t.Run(test.name, func(t *testing.T) { | ||
results := scanHCL(test.source, t) | ||
assertCheckCode(t, test.mustIncludeResultCode, test.mustExcludeResultCode, results) | ||
}) | ||
} | ||
|
||
} |