Skip to content

Commit 4072d75

Browse files
Merge pull request #1457 from devampkid:cloudflare-secret-detector
PiperOrigin-RevId: 871246001
2 parents 1b76376 + f22f593 commit 4072d75

File tree

13 files changed

+1318
-335
lines changed

13 files changed

+1318
-335
lines changed

binary/proto/scan_result.proto

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ message SecretData {
802802
DenoPat deno_pat = 73;
803803
HerokuSecretKey heroku_secret_key = 74;
804804
NpmJsAccessToken npmjs_access_token = 75;
805+
CloudflareAPIToken cloudflare_api_token = 76;
805806
}
806807

807808
message GCPSAK {
@@ -898,6 +899,10 @@ message SecretData {
898899
string username = 2;
899900
}
900901

902+
message CloudflareAPIToken {
903+
string token = 1;
904+
}
905+
901906
message DenoPat {
902907
string pat = 1;
903908
}

binary/proto/scan_result_go_proto/scan_result.pb.go

Lines changed: 401 additions & 335 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

binary/proto/secret.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
velesazurestorageaccountaccesskey "github.com/google/osv-scalibr/veles/secrets/azurestorageaccountaccesskey"
3131
velesazuretoken "github.com/google/osv-scalibr/veles/secrets/azuretoken"
3232
velescircleci "github.com/google/osv-scalibr/veles/secrets/circleci"
33+
"github.com/google/osv-scalibr/veles/secrets/cloudflareapitoken"
3334
"github.com/google/osv-scalibr/veles/secrets/cratesioapitoken"
3435
velescursorapikey "github.com/google/osv-scalibr/veles/secrets/cursorapikey"
3536
"github.com/google/osv-scalibr/veles/secrets/denopat"
@@ -148,6 +149,8 @@ func velesSecretToProto(s veles.Secret) (*spb.SecretData, error) {
148149
return mysqlMyloginSectionToProto(t), nil
149150
case dockerhubpat.DockerHubPAT:
150151
return dockerHubPATToProto(t), nil
152+
case cloudflareapitoken.CloudflareAPIToken:
153+
return cloudflareAPITokenToProto(t), nil
151154
case denopat.DenoUserPAT:
152155
return denoUserPATToProto(t), nil
153156
case denopat.DenoOrgPAT:
@@ -429,6 +432,16 @@ func denoOrgPATToProto(s denopat.DenoOrgPAT) *spb.SecretData {
429432
}
430433
}
431434

435+
func cloudflareAPITokenToProto(s cloudflareapitoken.CloudflareAPIToken) *spb.SecretData {
436+
return &spb.SecretData{
437+
Secret: &spb.SecretData_CloudflareApiToken{
438+
CloudflareApiToken: &spb.SecretData_CloudflareAPIToken{
439+
Token: s.Token,
440+
},
441+
},
442+
}
443+
}
444+
432445
func digitaloceanAPIKeyToProto(s velesdigitalocean.DigitaloceanAPIToken) *spb.SecretData {
433446
return &spb.SecretData{
434447
Secret: &spb.SecretData_Digitalocean{
@@ -1157,6 +1170,8 @@ func velesSecretToStruct(s *spb.SecretData) (veles.Secret, error) {
11571170
return mysqlMyloginSectionToStruct(s.GetMysqlMyloginSection()), nil
11581171
case *spb.SecretData_DockerHubPat_:
11591172
return dockerHubPATToStruct(s.GetDockerHubPat()), nil
1173+
case *spb.SecretData_CloudflareApiToken:
1174+
return cloudflareAPITokenToStruct(s.GetCloudflareApiToken()), nil
11601175
case *spb.SecretData_DenoPat_:
11611176
return denoPATToStruct(s.GetDenoPat()), nil
11621177
case *spb.SecretData_GitlabPat_:
@@ -1422,6 +1437,12 @@ func dockerHubPATToStruct(kPB *spb.SecretData_DockerHubPat) dockerhubpat.DockerH
14221437
}
14231438
}
14241439

1440+
func cloudflareAPITokenToStruct(kPB *spb.SecretData_CloudflareAPIToken) cloudflareapitoken.CloudflareAPIToken {
1441+
return cloudflareapitoken.CloudflareAPIToken{
1442+
Token: kPB.GetToken(),
1443+
}
1444+
}
1445+
14251446
func denoPATToStruct(kPB *spb.SecretData_DenoPat) veles.Secret {
14261447
pat := kPB.GetPat()
14271448
if len(pat) >= 4 && pat[:4] == "ddp_" {

docs/supported_inventory_types.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ See the docs on [how to add a new Extractor](/docs/new_extractor.md).
125125
| Bitbucket | `secrets/bitbucketcredentials` |
126126
| CircleCI Personal Access Token | `secrets/circlecipat` |
127127
| CircleCI Project Token | `secrets/circleciproject` |
128+
| Cloudflare API Token | `secrets/cloudflareapitoken` |
128129
| Crates.io API Token | `secrets/cratesioapitoken` |
129130
| Cursor API key | `secrets/cursorapikey` |
130131
| DigitalOcean API key | `secrets/digitaloceanapikey` |

enricher/enricherlist/list.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
"github.com/google/osv-scalibr/veles/secrets/anthropicapikey"
4343
"github.com/google/osv-scalibr/veles/secrets/awsaccesskey"
4444
"github.com/google/osv-scalibr/veles/secrets/circleci"
45+
"github.com/google/osv-scalibr/veles/secrets/cloudflareapitoken"
4546
"github.com/google/osv-scalibr/veles/secrets/cratesioapitoken"
4647
"github.com/google/osv-scalibr/veles/secrets/cursorapikey"
4748
"github.com/google/osv-scalibr/veles/secrets/denopat"
@@ -125,6 +126,7 @@ var (
125126
fromVeles(slacktoken.NewAppConfigRefreshTokenValidator(), "secrets/slackconfigrefreshtokenvalidate", 0),
126127
fromVeles(slacktoken.NewAppConfigAccessTokenValidator(), "secrets/slackconfigaccesstokenvalidate", 0),
127128
fromVeles(dockerhubpat.NewValidator(), "secrets/dockerhubpatvalidate", 0),
129+
fromVeles(cloudflareapitoken.NewValidator(), "secrets/cloudflareapitokenvalidate", 0),
128130
fromVeles(denopat.NewUserTokenValidator(), "secrets/denopatuservalidate", 0),
129131
fromVeles(denopat.NewOrgTokenValidator(), "secrets/denopatorgvalidate", 0),
130132
fromVeles(gcpsak.NewValidator(), "secrets/gcpsakvalidate", 0),

extractor/filesystem/list/list.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ import (
103103
"github.com/google/osv-scalibr/extractor/filesystem/sbom/cdx"
104104
"github.com/google/osv-scalibr/extractor/filesystem/sbom/spdx"
105105
"github.com/google/osv-scalibr/extractor/filesystem/secrets/awsaccesskey"
106+
"github.com/google/osv-scalibr/extractor/filesystem/secrets/cloudflareapitoken"
106107
"github.com/google/osv-scalibr/extractor/filesystem/secrets/convert"
107108
"github.com/google/osv-scalibr/extractor/filesystem/secrets/gitbasicauth/bitbucket"
108109
"github.com/google/osv-scalibr/extractor/filesystem/secrets/gitbasicauth/codecatalyst"
@@ -330,6 +331,7 @@ var (
330331
codecatalyst.Name: {codecatalyst.New},
331332
codecommit.Name: {codecommit.New},
332333
bitbucket.Name: {bitbucket.New},
334+
cloudflareapitoken.Name: {cloudflareapitoken.New},
333335
}
334336

335337
// SecretDetectors for Detector interface.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2026 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 cloudflareapitoken extends the veles cloudflareapitoken.Detector to search inside
16+
// Cloudflare-specific configuration files
17+
package cloudflareapitoken
18+
19+
import (
20+
"strings"
21+
22+
"github.com/google/osv-scalibr/extractor/filesystem"
23+
"github.com/google/osv-scalibr/extractor/filesystem/secrets/convert"
24+
"github.com/google/osv-scalibr/veles/secrets/cloudflareapitoken"
25+
26+
cpb "github.com/google/osv-scalibr/binary/proto/config_go_proto"
27+
)
28+
29+
const (
30+
// Name is the name of the extractor
31+
Name = "secrets/cloudflareapitoken"
32+
// Version is the version of the extractor
33+
Version = 0
34+
)
35+
36+
// FileRequired reports whether the plugin should scan the given file.
37+
// It restricts scanning to paths that contain "cloudflare" in the path or filename.
38+
func FileRequired(api filesystem.FileAPI) bool {
39+
path := strings.ToLower(api.Path())
40+
return strings.Contains(path, "cloudflare")
41+
}
42+
43+
// New returns a filesystem.Extractor which extracts Cloudflare API Tokens using the cloudflareapitoken.Detector
44+
func New(_ *cpb.PluginConfig) (filesystem.Extractor, error) {
45+
return convert.FromVelesDetectorWithRequire(
46+
cloudflareapitoken.NewDetector(), Name, Version, FileRequired,
47+
), nil
48+
}

0 commit comments

Comments
 (0)