diff --git a/assets/queries/common/passwords_and_secrets/regex_rules.json b/assets/queries/common/passwords_and_secrets/regex_rules.json index 4620f0285cd..3228d649743 100644 --- a/assets/queries/common/passwords_and_secrets/regex_rules.json +++ b/assets/queries/common/passwords_and_secrets/regex_rules.json @@ -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*" @@ -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*;" } ] }, @@ -350,6 +358,10 @@ { "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*" @@ -373,6 +385,10 @@ { "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*" diff --git a/assets/queries/common/passwords_and_secrets/test/negative60.proto b/assets/queries/common/passwords_and_secrets/test/negative60.proto new file mode 100644 index 00000000000..63d53613600 --- /dev/null +++ b/assets/queries/common/passwords_and_secrets/test/negative60.proto @@ -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 +} \ No newline at end of file diff --git a/assets/queries/common/passwords_and_secrets/test/positive56.proto b/assets/queries/common/passwords_and_secrets/test/positive56.proto new file mode 100644 index 00000000000..4367e728812 --- /dev/null +++ b/assets/queries/common/passwords_and_secrets/test/positive56.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +// This sample should not flag the message defined only the exposed secrets in comments : +// "password" = "test_sample" +// "secret_key" : minimum_ten_characters +// "unsafe_token" : "is_this_safe" +// 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 InocentMessage { + google.protobuf.StringValue safe_value = 1; + double not_a_password = 2; + float not_a_token = 3; + string not_an_encryption_key = 4; +} \ No newline at end of file diff --git a/assets/queries/common/passwords_and_secrets/test/positive_expected_result.json b/assets/queries/common/passwords_and_secrets/test/positive_expected_result.json index e29ad869f20..9eca41250a0 100644 --- a/assets/queries/common/passwords_and_secrets/test/positive_expected_result.json +++ b/assets/queries/common/passwords_and_secrets/test/positive_expected_result.json @@ -460,5 +460,23 @@ "severity": "HIGH", "line": 4, "fileName": "positive55.json" + }, + { + "queryName": "Passwords And Secrets - Generic Password", + "severity": "HIGH", + "line": 4, + "fileName": "positive56.proto" + }, + { + "queryName": "Passwords And Secrets - Generic Secret", + "severity": "HIGH", + "line": 5, + "fileName": "positive56.proto" + }, + { + "queryName": "Passwords And Secrets - Generic Token", + "severity": "HIGH", + "line": 6, + "fileName": "positive56.proto" } ] \ No newline at end of file diff --git a/pkg/engine/secrets/inspector_test.go b/pkg/engine/secrets/inspector_test.go index 2b5bbf12b55..f642d0e1772 100644 --- a/pkg/engine/secrets/inspector_test.go +++ b/pkg/engine/secrets/inspector_test.go @@ -260,6 +260,34 @@ var OriginalData7 = `# kics-scan disable=baee238e-1921-4801-9c3f-79ae1d7b2cbc register: result ` +var OriginalData8 = ` + syntax = "proto3"; + + package com.example.security_test.v1; + + import "google/protobuf/wrappers.proto"; + + message ResultsThatFlag { + 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= 1; // 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 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 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 +` + var testInspectInput = []struct { name string files model.FileMetadatas @@ -418,6 +446,21 @@ var testInspectInput = []struct { wantVuln: []model.Vulnerability{}, wantErr: false, }, + { + name: "valid_no_results", + files: model.FileMetadatas{ + { + ID: "a6fbadc6-da29-4340-8d56-aa26a8852526", + Document: model.Document{}, + OriginalData: OriginalData8, + LinesOriginalData: utils.SplitLines(OriginalData8), + Kind: "PROTO", + FilePath: "assets/queries/common/passwords_and_secrets/test/negative60.proto", + }, + }, + wantVuln: []model.Vulnerability{}, + wantErr: false, + }, } var testNewInspectorInputs = []struct {