Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions assets/queries/common/passwords_and_secrets/regex_rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
{
"description": "Allow password retrieved from ARM parameters",
"regex": "(?i)['\"]?password['\"]?\\s*[:=]\\s*['\"]?\\s*,\\s*parameters\\(['\"]([a-zA-Z][a-zA-Z0-9_-]*)['\"]['\"]?\\)"
},
{
"description": "Avoiding Proto File fields",
"regex": "(?i)password\\s*=\\s*[1-9][0-9]{0,8}\\s*;"
}
],
"specialMask": "(?i)['\"]?password['\"]?\\s*[:=]\\s*"
Expand Down Expand Up @@ -263,7 +267,7 @@
{
"id": "7f370dd5-eea3-4e5f-8354-3cb2506f9f13",
"name": "Generic Access Key",
"regex": "(?i)^\\s*['\"]?(access)[_]?key['\"]?\\s*[:=]\\s*['\"]?([[A-Za-z0-9\/~^_!@&%()=?*+-]+)['\"]?",
"regex": "(?i)^\\s*['\"]?access[_]?key['\"]?\\s*[:=]\\s*['\"]?([[A-Za-z0-9\/~^_!@&%()=?*+-]+)['\"]?",
"specialMask": "(?i)['\"]?access[_]?key['\"]?\\s*[:=]\\s*"
},
{
Expand All @@ -279,6 +283,10 @@
{
"description": "Avoid Docker Compose secrets paths",
"regex": "(?i)['\"]?private[_]?key['\"]?\\s*[:=]\\s*['\"]?/run/secrets/\\w+['\"]?"
},
{
"description": "Avoiding Proto File fields",
"regex": "(?i)private[_]?key\\s*=\\s*[1-9][0-9]{0,8}\\s*;"
}
]
},
Expand Down Expand Up @@ -313,7 +321,7 @@
},
{
"description": "Avoiding TF resource access",
"regex": "(?i)['\"]?token(_)?(key)?['\"]?\\s*=\\s*([a-zA-z_]+(.))?[a-zA-z_]+(.)[a-zA-z_]+(.)[a-zA-z_]+"
"regex": "(?i)['\"]?token(_)?(key)?['\"]?\\s*[:=]\\s*(([a-zA-Z_]+(\\[([a-zA-Z_]+\\.[a-zA-Z_]+.*|\\d+)\\])?\\.[a-zA-Z_]+(\\[([a-zA-Z_]+\\.[a-zA-Z_]+.*|\\d+)\\])?)\\s*([\\[\\.\\)\\]\\}\\$]|(:\\s*null))|null)"
},
{
"description": "Avoiding TF creation token",
Expand All @@ -339,40 +347,44 @@
"description": "Avoiding next_token Var",
"regex": "(?i)['\"]?next(_)?token['\"]?\\s*[:=]\\s*['\"]?([[A-Za-z0-9/~^_!@&%()=?*+-]+)['\"]?"
},
{
"description": "Avoiding next_token Var",
"regex": "(?i)['\"]?next(_)?token['\"]?\\s*[:=]\\s*['\"]?([[A-Za-z0-9/~^_!@&%()=?*+-]+)['\"]?"
},
{
"description": "Avoiding references to module outputs in Bicep",
"regex": "(?i)token(_)?(key)?\\s*[:=]\\s*([a-zA-Z][a-zA-Z0-9_]*)\\.outputs\\.([a-zA-Z][a-zA-Z0-9_]*)"
},
{
"description": "Avoiding Run After Triggers (if written in conformity with best practices)",
"regex": "(?i)['\"](HTTP|Parse_JSON|Try|Catch)_-_(Get_)?OAuth_Token['\"]?\\s*[:=]\\s*['\"]?([[A-Za-z0-9/~^_!@&%()=?*+-]+)['\"]?"
},
{
"description": "Avoiding Proto File fields",
"regex": "(?i)token(_)?(key)?\\s*=\\s*[1-9][0-9]{0,8}\\s*;"
}
],
"specialMask": "(?i)['\"]?token(_)?(key)?['\"]?\\s*[:=]\\s*"

},
{
"id": "e0f01838-b1c2-4669-b84b-981949ebe5ed",
"id": "0ec60fb3-5b78-4da0-bea0-b854fd9bf8b9",
"name": "CloudFormation Secret Template",
"regex": "(?i)['\"]?SecretStringTemplate['\"]?\\s*:\\s*['\"]?{([\\\":A-Za-z0-9/~^_!@&%()=?*+-]{10,})}",
"specialMask": "(?i)['\"]?SecretStringTemplate['\"]?\\s*:\\s*"
},
{
"id": "9fb1cd65-7a07-4531-9bcf-47589d0f82d6",
"name": "Encryption Key",
"regex": "(?i)['\"]?encryption[_]?key['\"]?\\s*[:=]\\s*['\"]?([[A-Za-z0-9/~^_!@&%()=?*+-]+)['\"]?",
"regex": "(?i)['\"]?encryption[_]?key['\"]?\\s*[:=]\\s*['\"]?[A-Za-z0-9/~^_!@&%()=?*+-]+['\"]?",
"allowRules": [
{
"description": "Avoiding TF resource access",
"regex": "(?i)['\"]?encryption[_]?key['\"]?\\s*=\\s*([a-zA-z_]+(.))?[a-zA-z_]+(.)[a-zA-z_]+(.)[a-zA-z_]+"
"regex": "(?i)['\"]?encryption[_]?key['\"]?\\s*[:=]\\s*(([a-zA-Z_]+(\\[([a-zA-Z_]+\\.[a-zA-Z_]+.*|\\d+)\\])?\\.[a-zA-Z_]+(\\[([a-zA-Z_]+\\.[a-zA-Z_]+.*|\\d+)\\])?)\\s*([\\[\\.\\)\\]\\}\\$]|(:\\s*null))|null)"
},
{
"description": "Avoiding CLoudformation KeyName",
"regex": "['\"]?EncryptionKey['\"]?\\s*[:=]\\s*['\"]?([A-Za-z0-9/~^_!@&%()=?*+-.]+)['\"]?"
},
{
"description": "Avoiding Proto File fields",
"regex": "(?i)encryption[_]?key\\s*=\\s*[1-9][0-9]{0,8}\\s*;"
}
],
"specialMask": "(?i)['\"]?encryption[_]?key['\"]?\\s*[:=]\\s*"
Expand Down
114 changes: 111 additions & 3 deletions assets/queries/common/passwords_and_secrets/test/negative28.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,112 @@
provider rancher2 {
api_url = data.terraform_remote_state.rancher.outputs.api_url
token_key = data.terraform_remote_state.rancher.outputs.token_key
# Sample to test 'Generic Token' - allow TF resource access rule
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

variable "auth_token" {
description = "Authentication token"
type = string
sensitive = true
}

variable "environment" {
description = "Deployment environment"
type = string
default = "production"
}

variable "enabled" {
description = "Whether to enable resources"
type = bool
default = true
}

variable "clients" {
description = "Client configurations"
type = object({
oauth = map(object({
enabled = bool
}))
})
}

resource "aws_secretsmanager_secret_version" "token_version" {
for_each = { for k, v in var.clients.oauth : k => v if var.enabled }

secret_id = aws_secretsmanager_secret.client_token_secret[each.key].id
secret_string = jsonencode({ "client" : each.key, "token" : random_password.client_token[each.key].result })
}

resource "aws_secretsmanager_secret_version" "token_version_2" {
for_each = { for k, v in var.clients.oauth : k => v if var.enabled }

secret_id = aws_secretsmanager_secret.client_token_secret[each.key].id
secret_string = jsonencode({ "client" : each.key, "token" : random_password[each.key].client_token.result })
}

resource "aws_secretsmanager_secret_version" "token_version_3" {
for_each = { for k, v in var.clients.oauth : k => v if var.enabled }

secret_id = aws_secretsmanager_secret.client_token_secret[each.key].id
secret_string = jsonencode({ "client" : each.key, "token" : random_password["index"].client_token.result })
}

resource "aws_lb_listener" "https" {
count = var.enabled ? 1 : 0
load_balancer_arn = aws_lb.main[0].arn
port = 443
protocol = "HTTPS"

default_action {
type = "forward"
target_group_arn = [for t in aws_lb_target_group.app : t.token_key]
}
}

resource "aws_lb_listener" "https_null" {
count = var.enabled ? 1 : 0
load_balancer_arn = aws_lb.main[0].arn
port = 443
protocol = "HTTPS"

default_action {
type = "fixed-response"
token_key = null
}
}
module "auth_service" {
source = "./modules/auth"

token = var.auth_token
}
module "api_gateway" {
source = "./modules/gateway"

token = module.auth_service.token_output.value
}
module "legacy_service" {
source = "./modules/legacy"

token = data.aws_secretsmanager_secret_version.existing_token.secret_string
}

locals {
token_config = {
value = aws_secretsmanager_secret.client_token_secret["primary"].arn
}
}

module "monitoring" {
source = "./modules/monitoring"

token = local.token_config.value
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
syntax = "proto3";

// Contains "secret", "key", "password" and "token" keywords - would flag if not for allow rules
// Note - This is as valid proto file that generates output with "protoc" command as of version "libprotoc 34.0"

package com.example.security_test.v1;

import "google/protobuf/wrappers.proto";

message SampleMessageNegative {
google.protobuf.StringValue refresh_token = 536870911; // if value is larger - out of range error "Field numbers cannot be greater than 536870911." - Generic Token
google.protobuf.StringValue access_token= 111111111; // Generic Token
google.protobuf.StringValue id_token = 3; // Generic Token
google.protobuf.StringValue bearer_toaken = 4;;; // Generic Token
google.protobuf.StringValue api_token = 7 ; // Generic Token
google.protobuf.StringValue token = 8; // Generic Token
google.protobuf.StringValue aws_session_token = 9; // Generic Token
google.protobuf.StringValue sas_token = 12; // Generic Token
google.protobuf.StringValue auth_token = 13; // Generic Token
google.protobuf.StringValue bot_token = 14; // Generic Token
google.protobuf.StringValue callback_token = 32; // Generic Token
google.protobuf.StringValue k8s_service_account_token = 33; // Generic Token
google.protobuf.StringValue registry_token = 34; // Generic Token
google.protobuf.StringValue deploy_token = 35; // Generic Token
google.protobuf.StringValue ci_token = 36; // Generic Token
google.protobuf.StringValue npm_token = 37; // Generic Token
google.protobuf.StringValue pypi_token = 38; // Generic Token
google.protobuf.StringValue app_installation_token = 20; // Generic Token
google.protobuf.StringValue twilio_auth_token = 21; // Generic Token
google.protobuf.StringValue twilio_auth_token_key = 121; // Generic Token
google.protobuf.StringValue test_token_ = 122 ; // Generic Token
google.protobuf.StringValue sonar_token = 39;google.protobuf.StringValue codecov_token = 40;// trailing comment test - Generic Token
google.protobuf.StringValue jwt_private_key = 25; // Generic Private Key
google.protobuf.StringValue ssh_private_key = 26; // Generic Private Key
google.protobuf.StringValue tls_private_key = 27; // Generic Private Key
google.protobuf.StringValue ca_private_key = 28 ; // Generic Private Key
google.protobuf.StringValue cosign_private_key = 41; // Generic Private Key
google.protobuf.StringValue service_account_private_key = 30; // Generic Private Key
google.protobuf.StringValue app_private_key = 19; // Generic Private Key
google.protobuf.StringValue gcp_private_key = 10; // Generic Private Key
google.protobuf.StringValue private_key = 5; // Generic Private Key
google.protobuf.StringValue sp_private_key = 6; // Generic Private Key
google.protobuf.StringValue encryption_key = 22; // Encryption Key
google.protobuf.StringValue data_encryption_key= 23 ; // Encryption Key
google.protobuf.StringValue key_encryption_key=24; // Encryption Key
google.protobuf.StringValue registry_password = 104; // Generic Password
google.protobuf.StringValue artifactory_password = 107 ; // Generic Password
google.protobuf.StringValue nexus_password = 108; // Generic Password
string password = 64; // Generic Password
}
134 changes: 134 additions & 0 deletions assets/queries/common/passwords_and_secrets/test/negative61.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Sample for 'Encryption Key' - avoiding TF resource access rule
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

variable "encryption_key" {
description = "Encryption key from external config"
type = string
sensitive = true
}

variable "environment" {
description = "Deployment environment"
type = string
default = "production"
}

variable "enabled" {
description = "Whether to enable resources"
type = bool
default = true
}

variable "clients" {
description = "Client configurations"
type = object({
storage = map(object({
enabled = bool
}))
})
}

resource "aws_kms_key" "client_encryption_key" {
for_each = { for k, v in var.clients.storage : k => v if var.enabled }

description = "KMS key for ${each.key}"
deletion_window_in_days = 30
enable_key_rotation = true
}

resource "aws_kms_alias" "client_encryption_alias" {
for_each = { for k, v in var.clients.storage : k => v if var.enabled }

name = "alias/${each.key}-encryption"
target_key_id = aws_kms_key.client_encryption_key[each.key].key_id
}

module "storage" {
for_each = { for k, v in var.clients.storage : k => v if var.enabled }
source = "./modules/storage"

encryption_key = aws_kms_key.client_encryption_key[each.key].arn
}

module "storage_2" {
for_each = { for k, v in var.clients.storage : k => v if var.enabled }
source = "./modules/storage"

encryption_key = aws_kms_key[each.key].client_encryption_key.arn
}

module "storage_3" {
for_each = { for k, v in var.clients.storage : k => v if var.enabled }
source = "./modules/storage"

encryption_key = aws_kms_key["index"].client_encryption_key.arn
}

resource "aws_s3_bucket_server_side_encryption_configuration" "bucket_enc" {
count = var.enabled ? 1 : 0
bucket = aws_s3_bucket.main[0].id

rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
encryption_key = [for k in aws_kms_key.client_encryption_key : k.arn]
}
}
}

module "optional_encryption" {
source = "./modules/storage"

encryption_key = null
}

module "database" {
source = "./modules/database"

encryption_key = var.encryption_key
}

module "encryption" {
source = "./modules/encryption"

environment = var.environment
}

module "app" {
source = "./modules/app"

encryption_key = module.encryption.key_output.value
}

data "aws_kms_key" "existing" {
key_id = "alias/existing-encryption-key"
}

module "legacy" {
source = "./modules/legacy"

encryption_key = data.aws_kms_key.existing.arn
}

locals {
encryption_config = {
key_arn = aws_kms_key.client_encryption_key["primary"].arn
}
}

module "monitoring" {
source = "./modules/monitoring"

encryption_key = local.encryption_config.key_arn
}
Loading
Loading