github.com/google/osv-scalibr@v0.4.1/veles/secrets/awsaccesskey/detector_test.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package awsaccesskey_test 16 17 import ( 18 "strings" 19 "testing" 20 21 "github.com/google/go-cmp/cmp" 22 "github.com/google/go-cmp/cmp/cmpopts" 23 "github.com/google/osv-scalibr/veles" 24 "github.com/google/osv-scalibr/veles/secrets/awsaccesskey" 25 ) 26 27 func TestDetector_Detect(t *testing.T) { 28 engine, err := veles.NewDetectionEngine([]veles.Detector{awsaccesskey.NewDetector()}) 29 if err != nil { 30 t.Fatal(err) 31 } 32 33 tests := []struct { 34 name string 35 input string 36 want []veles.Secret 37 }{ 38 // --- Empty or invalid input --- 39 { 40 name: "empty_input", 41 input: "", 42 want: nil, 43 }, 44 { 45 name: "invalid_access_id_format_-_wrong prefix", 46 input: "WRONG984R439T439HTH439T403TJ430TK340TK43T430JT430TK430JT043JT:32r923jr023rk320rk2a3rkB34tj340r32Ckt433", 47 want: nil, 48 }, 49 { 50 name: "invalid_secret_format_-_too short", 51 input: "GOOG1984R439T439HTH439T403TJ430TK340TK43T430JT430TK430JT043JT:32r923jr023rk320rk2a3rkB34tj3", 52 want: nil, 53 }, 54 // --- Only access ID or Secret --- 55 { 56 name: "access_ID_but_no_secret", 57 input: `app_id: AIKA1984R439T439HTH4`, 58 want: nil, 59 }, 60 { 61 name: "secret_but_no_access_ID", 62 input: `app_secret: 32r923jr023rk320rk2a3rkB34tj340r32Ckt433`, 63 want: nil, 64 }, 65 // -- Single access ID and Secret in close proximity (happy path) --- 66 { 67 name: "aws credentials", 68 input: `[default] 69 aws_access_key_id = AIKA1984R439T439HTH4 70 aws_secret_access_key = 32r923jr023rk320rk2a3rkB34tj340r32Ckt433`, 71 want: []veles.Secret{ 72 awsaccesskey.Credentials{ 73 AccessID: "AIKA1984R439T439HTH4", 74 Secret: "32r923jr023rk320rk2a3rkB34tj340r32Ckt433", 75 }, 76 }, 77 }, 78 { 79 name: "access_ID_and_secret_in_close_proximity_-_no_space", 80 input: `AIKA1984R439T439HTH4:32r923jr023rk320rk2a3rkB34tj340r32Ckt433`, 81 want: []veles.Secret{ 82 awsaccesskey.Credentials{ 83 AccessID: "AIKA1984R439T439HTH4", 84 Secret: "32r923jr023rk320rk2a3rkB34tj340r32Ckt433", 85 }, 86 }, 87 }, 88 { 89 name: "access_ID_and_secret_in_close_proximity_in_json_format", 90 input: `{ 91 "access_id": "AIKA1984R439T439HTH4", 92 "secret": "32r923jr023rk320rk2a3rkB34tj340r32Ckt433" 93 }`, 94 want: []veles.Secret{ 95 awsaccesskey.Credentials{ 96 AccessID: "AIKA1984R439T439HTH4", 97 Secret: "32r923jr023rk320rk2a3rkB34tj340r32Ckt433", 98 }, 99 }, 100 }, 101 { 102 name: "valid_formats_mixed_with_invalid", 103 input: `valid_id: AIKA1984R439T439HTH4 104 invalid_id: 123-invalid.apps.googleusercontent.com 105 valid_secret: 32r923jr023rk320rk2a3rkB34tj340r32Ckt433 106 invalid_secret: WRONG-InvalidSecret123456789012`, 107 want: []veles.Secret{ 108 awsaccesskey.Credentials{ 109 AccessID: "AIKA1984R439T439HTH4", 110 Secret: "32r923jr023rk320rk2a3rkB34tj340r32Ckt433", 111 }, 112 }, 113 }, 114 // -- Multiple access ID and Secret in close proximity --- 115 { 116 name: "complex_file_with_multiple_access_ID_and_secret_-_test_proximity", 117 input: `config_app1: 118 AIKA1984R439T439HTH4 119 32r923jr023rk320rk2a3rkB34tj340r32Ckt433 120 121 config_app2: 122 AIKA1984R439T439HTH3 123 32r923jr023rk320rk2a3rkB34tj340r32Ckt432`, 124 want: []veles.Secret{ 125 awsaccesskey.Credentials{ 126 AccessID: "AIKA1984R439T439HTH4", 127 Secret: "32r923jr023rk320rk2a3rkB34tj340r32Ckt433", 128 }, 129 awsaccesskey.Credentials{ 130 AccessID: "AIKA1984R439T439HTH3", 131 Secret: "32r923jr023rk320rk2a3rkB34tj340r32Ckt432", 132 }, 133 }, 134 }, 135 // -- Multiple access ID and Secret in with varied proximity --- 136 { 137 name: "complex_file_with_access_ID_and_secret_-_far_apart_(no_pairing)", 138 input: `config_app1: 139 AIKA1984R439T439HTH4` + strings.Repeat("\nfiller line with random data", 500) + ` 140 config_app2: 141 32r923jr023rk320rk2a3rkB34tj340r32Ckt432`, 142 want: nil, 143 }, 144 } 145 146 for _, tc := range tests { 147 t.Run(tc.name, func(t *testing.T) { 148 got, err := engine.Detect(t.Context(), strings.NewReader(tc.input)) 149 if err != nil { 150 t.Errorf("Detect() error: %v, want nil", err) 151 } 152 if diff := cmp.Diff(tc.want, got, cmpopts.EquateEmpty()); diff != "" { 153 t.Errorf("Detect() diff (-want +got):\n%s", diff) 154 } 155 }) 156 } 157 }