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  }