github.com/google/osv-scalibr@v0.4.1/veles/secrets/recaptchakey/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 recaptchakey_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/recaptchakey" 25 ) 26 27 func TestDetector_Detect(t *testing.T) { 28 engine, err := veles.NewDetectionEngine([]veles.Detector{recaptchakey.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 { 39 name: "empty_input", 40 input: "", 41 want: nil, 42 }, 43 { 44 name: "random_input", 45 input: "Some random text", 46 want: nil, 47 }, 48 { 49 name: "python", 50 input: ` 51 RECAPTCHA_PUBLIC_KEY = '6LcA1x0UAAAAAF1b2Qp9Zp3t0TestKeyPublic01' 52 RECAPTCHA_PRIVATE_KEY = '6LeA1x0UAAAAAG1b2Qp9Zp3t0TestKeyPrivate1'`, 53 want: []veles.Secret{ 54 recaptchakey.Key{ 55 Secret: "6LeA1x0UAAAAAG1b2Qp9Zp3t0TestKeyPrivate1", 56 }, 57 }, 58 }, 59 { 60 name: "yaml_simple", 61 input: ` 62 recaptcha_site_key: 6LcD4a3XAA-AAE7n9Gu2St3y3TestKeyPublic02 63 recaptcha_secret_key: 6LeD4a3XAAAAA-7n9Gu2St3y3TestKeyPrivate2 64 `, 65 want: []veles.Secret{ 66 recaptchakey.Key{ 67 Secret: "6LeD4a3XAAAAA-7n9Gu2St3y3TestKeyPrivate2", 68 }, 69 }, 70 }, 71 { 72 name: "yaml_multiline", 73 input: ` 74 recaptcha: 75 public_key: 6LcA1x0UAAAAAF-1b2Qp9Zp3t-TestKeyPublic3 76 private_key: 6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3 77 `, 78 want: []veles.Secret{ 79 recaptchakey.Key{ 80 Secret: "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3", 81 }, 82 }, 83 }, 84 { 85 name: "yaml_multiline_another_key", 86 input: ` 87 recaptcha: 88 public_key: 6LcA1x0UAAAAAF-1b2Qp9Zp3t-TestKeyPublic3 89 private_key: *** 90 another_key: 91 private_key: 6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3 92 `, 93 want: nil, 94 }, 95 { 96 name: "yaml_indented", 97 input: ` 98 someIndentation: 99 recaptcha: 100 public_key: 6LcA1x0UAAAAAF-1b2Qp9Zp3t-TestKeyPublic3 101 private_key: 6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3 102 `, 103 want: []veles.Secret{ 104 recaptchakey.Key{Secret: "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"}, 105 }, 106 }, 107 { 108 name: "no_space_env", 109 input: ` 110 RECAPTCHA_PRIVATE_KEY=6LeA1x0UAAAAAG1b2Qp9Zp3t0TestKeyPrivate1 111 `, 112 want: []veles.Secret{ 113 recaptchakey.Key{Secret: "6LeA1x0UAAAAAG1b2Qp9Zp3t0TestKeyPrivate1"}, 114 }, 115 }, 116 { 117 name: "simple_yaml", 118 input: ` 119 # This is a comment 120 recaptcha_secret_key: 6LeF9x0UAAAAAG1b2Qp9Zp3t0PrivateComment1 121 # Another comment 122 recaptcha_site_key: 6LcF9x0UAAAAAF1b2Qp9Zp3t01PublicComment1 123 `, 124 want: []veles.Secret{ 125 recaptchakey.Key{Secret: "6LeF9x0UAAAAAG1b2Qp9Zp3t0PrivateComment1"}, 126 }, 127 }, 128 { 129 name: "yaml_with_nested_comments", 130 input: ` 131 reCaptcha: 132 # Inline comment for public key 133 public_key: 6LcH1x0UAAAAAF-1b2Qp9Z11p3t-PublicNested 134 private_key: 6LeH1x0UAAAAAG1r3Ky6Wx7c711PrivateNested 135 # Comment outside mapping 136 `, 137 want: []veles.Secret{ 138 recaptchakey.Key{Secret: "6LeH1x0UAAAAAG1r3Ky6Wx7c711PrivateNested"}, 139 }, 140 }, 141 { 142 name: "multiple_keys_env", 143 input: ` 144 RECAPTCHA_PRIVATE_KEY = '6LeA1x0UAAAAAG1b2Qp9Zp3t0TestKeyPrivate1' 145 recaptcha_secret_key: 6LeD4a3XAAAAA-7n9Gu2St3y3TestKeyPrivate2 146 `, 147 want: []veles.Secret{ 148 recaptchakey.Key{Secret: "6LeA1x0UAAAAAG1b2Qp9Zp3t0TestKeyPrivate1"}, 149 recaptchakey.Key{Secret: "6LeD4a3XAAAAA-7n9Gu2St3y3TestKeyPrivate2"}, 150 }, 151 }, 152 { 153 name: "invalid_key", 154 input: ` 155 NOT_A_KEY = "6LeD4a3XAAAAA-INVALID-1234567890" 156 `, 157 want: nil, 158 }, 159 { 160 name: "key_value_json", 161 input: ` 162 { 163 "recaptcha_public_key": "6LcA1x0UAAAAAF-1b2Qp9Zp3y3TestKeyPublic3", 164 "recaptcha_secret_key": "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3" 165 } 166 `, 167 want: []veles.Secret{ 168 recaptchakey.Key{Secret: "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"}, 169 }, 170 }, 171 { 172 name: "multiline_json", 173 input: `{ 174 "recaptcha": { 175 "public_key": "6LcA1x0UAAAAAF-1b2Qp9Zp3y3TestKeyPublic3", 176 "secret_key": "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3" 177 } 178 }`, 179 want: []veles.Secret{ 180 recaptchakey.Key{Secret: "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"}, 181 }, 182 }, 183 { 184 name: "inline_json", 185 input: `{"recaptcha": {"public_key": "6LcA1x0UAAAAAF-1b2Qp9Zp3y3TestKeyPublic3","secret_key": "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"}}`, 186 want: []veles.Secret{ 187 recaptchakey.Key{Secret: "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"}, 188 }, 189 }, 190 { 191 name: "escaped_json", 192 input: `{\n \"recaptcha\": {\n \"public_key\": \"6LcA1x0UAAAAAF-1b2Qp9Zp3y3TestKeyPublic3\",\n \"secret_key\": \"6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3\"\n }\n}`, 193 want: []veles.Secret{ 194 recaptchakey.Key{Secret: "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"}, 195 }, 196 }, 197 { 198 name: "escaped_key_value_json", 199 input: ` 200 { 201 "recaptcha_public_key": "6LcA1x0UAAAAAF-1b2Qp9Zp3y3TestKeyPublic3", 202 "recaptcha_secret_key": "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3" 203 } 204 `, 205 want: []veles.Secret{ 206 recaptchakey.Key{Secret: "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"}, 207 }, 208 }, 209 { 210 name: "space_in_between", 211 input: ` 212 recaptchaSecret 6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3 213 `, 214 want: []veles.Secret{ 215 recaptchakey.Key{Secret: "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"}, 216 }, 217 }, 218 { 219 name: "go", 220 input: ` 221 var recaptchaV3Secret = "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3" 222 `, 223 want: []veles.Secret{ 224 recaptchakey.Key{Secret: "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"}, 225 }, 226 }, 227 { 228 name: "go2", 229 input: ` 230 recaptchaV3Secret := "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3" 231 `, 232 want: []veles.Secret{ 233 recaptchakey.Key{Secret: "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"}, 234 }, 235 }, 236 { 237 name: "xml", 238 input: ` 239 <add key="reCaptchaSecret" value="6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"/> 240 `, 241 want: []veles.Secret{ 242 recaptchakey.Key{Secret: "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"}, 243 }, 244 }, 245 { 246 name: "url", 247 input: ` 248 captchaenterprise.googleapis.com/?secret=6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3 249 `, 250 want: []veles.Secret{ 251 recaptchakey.Key{Secret: "6LeH8e7VAAAAAG1r3Ky6Wx7c7TestKeyPrivate3"}, 252 }, 253 }, 254 } 255 256 for _, tc := range tests { 257 t.Run(tc.name, func(t *testing.T) { 258 got, err := engine.Detect(t.Context(), strings.NewReader(tc.input)) 259 if err != nil { 260 t.Errorf("Detect() error: %v, want nil", err) 261 } 262 if diff := cmp.Diff(tc.want, got, cmpopts.EquateEmpty()); diff != "" { 263 t.Errorf("Detect() diff (-want +got):\n%s", diff) 264 } 265 }) 266 } 267 }