* Update Cloudflare detectors for 2026+ prefixed credential formats
## Context/Background
Cloudflare is rolling out new prefixed credential formats in 2026.
The new formats (`cfk_`, `cfut_`, `cfat_`) are self-identifying via
prefix and do not need keyword proximity matching. Per project
convention, new token formats are added via the `Versioner` interface
with a `v1`/`v2` directory split.
Additionally, CA keys (Service Keys) are now deprecated.
## Changes in this commit
- cloudflareglobalapikey: split into `v1`/`v2` with `Versioner`
interface. v1 fixes legacy regex to `[a-f0-9]{37,45}` (lowercase
hex). v2 adds `cfk_` prefixed format detection.
- cloudflareapitoken: split into `v1`/`v2` with `Versioner`
interface. v2 adds `cfut_`/`cfat_` prefixed format detection.
`cfat_` (account tokens) route verification through the
account-scoped `/accounts/:id/tokens/verify` endpoint, extracting
account IDs from surrounding data.
- cloudflarecakey: add deprecation notice with changelog link.
- defaults.go: updated imports and registrations for versioned
scanners.
* Address PR feedback on Cloudflare detectors
## Context/Background
Addressing reviewer feedback from @MuneebUllahKhan222 and Cursor
Bugbot on PR #4830.
## Changes in this commit
- Verification functions now return `(bool, error)` with proper
indeterminate/determinate handling. Callsites use
`SetVerificationError`. Status checks use exact `http.StatusOK`
instead of range. Response bodies properly drained via
`io.Copy(io.Discard, ...)`.
- Extracted shared verification functions into `common.go` at each
detector package root (following the AWS detector pattern). v1 and
v2 both import from the parent package instead of v2 importing v1.
- Added integration tests for both v2 detectors with coverage for
`cfk_`, `cfut_`, and `cfat_` (including account-scoped
verification).
- `cfat_` tokens now pair with account IDs in `RawV2` regardless of
the `verify` flag, consistent with how `cfk_` pairs with emails.
* Resolved Comments
---------
Co-authored-by: Nicholas Comer <[email protected]>
69 lines
2.1 KiB
Go
69 lines
2.1 KiB
Go
package cloudflareapitoken
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
regexp "github.com/wasilibs/go-re2"
|
|
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
|
cfapitoken "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/cloudflareapitoken"
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/detector_typepb"
|
|
)
|
|
|
|
type Scanner struct{}
|
|
|
|
// Ensure the Scanner satisfies the interfaces at compile time.
|
|
var _ detectors.Detector = (*Scanner)(nil)
|
|
var _ detectors.Versioner = (*Scanner)(nil)
|
|
|
|
func (Scanner) Version() int { return 1 }
|
|
|
|
var (
|
|
client = common.SaneHttpClient()
|
|
|
|
keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"cloudflare"}) + `\b([A-Za-z0-9_-]{40})\b`)
|
|
)
|
|
|
|
// Keywords are used for efficiently pre-filtering chunks.
|
|
// Use identifiers in the secret preferably, or the provider name.
|
|
func (s Scanner) Keywords() []string {
|
|
return []string{"cloudflare"}
|
|
}
|
|
|
|
// FromData will find and optionally verify CloudflareApiToken secrets in a given set of bytes.
|
|
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) {
|
|
dataStr := string(data)
|
|
|
|
matches := keyPat.FindAllStringSubmatch(dataStr, -1)
|
|
|
|
for _, match := range matches {
|
|
resMatch := strings.TrimSpace(match[1])
|
|
|
|
s1 := detectors.Result{
|
|
DetectorType: detector_typepb.DetectorType_CloudflareApiToken,
|
|
Raw: []byte(resMatch),
|
|
SecretParts: map[string]string{"key": resMatch},
|
|
}
|
|
|
|
if verify {
|
|
isVerified, verificationErr := cfapitoken.VerifyUserToken(ctx, client, resMatch)
|
|
s1.Verified = isVerified
|
|
s1.SetVerificationError(verificationErr, resMatch)
|
|
}
|
|
|
|
results = append(results, s1)
|
|
}
|
|
|
|
return results, nil
|
|
}
|
|
|
|
func (s Scanner) Type() detector_typepb.DetectorType {
|
|
return detector_typepb.DetectorType_CloudflareApiToken
|
|
}
|
|
|
|
func (s Scanner) Description() string {
|
|
return "Cloudflare is a web infrastructure and website security company, providing content delivery network services, DDoS mitigation, Internet security, and distributed domain name server services. Cloudflare API tokens can be used to manage and interact with Cloudflare services."
|
|
}
|