Documentation
¶
Overview ¶
Package detect runs compiled rules over text fragments and produces findings.
Index ¶
- Constants
- Variables
- func Blocks(policy, confidence string) bool
- func BlocksFinding(policy, testFixtures string, f Finding) bool
- func ConfidenceRank(c string) int
- func DecodeBasicAuth(b64 string) (user, password string, ok bool)
- func EmbeddedReason(line, secret string) string
- func Fingerprint(f Finding) string
- func IsTestPath(path string) bool
- func MeetsSeverity(f Finding, min string) bool
- func NoiseReason(secret string, quoted bool, path string) string
- func Redact(f *Finding, pct int)
- func Shannon(s string) float64
- func ValidatorNames() []string
- type Detector
- type Finding
- type Fragment
- type IgnoreSet
- type Options
- type Result
- type Suppressed
Constants ¶
const ( ContextLocal = "local" // localhost, private network, docker-compose service, .env.test ContextExample = "example" // .env.example / .env.sample / templates )
Finding contexts. A credential for a local or development service, or in an example/template file, is still reported (a strict policy must see it), but it is capped at low confidence and does not block under balanced.
const ( High = "high" // provider-specific format, or four or more independent signals Medium = "medium" // three independent signals; blocks under balanced too Low = "low" // fewer signals, or a generic value in a test/example file: review under balanced )
Confidence levels are qualitative evidence levels, not probabilities: they say how strong the evidence is that a value is a live credential in production code, counted from independent signals (no single signal, in particular entropy, is enough). They are not calibrated against any dataset's labels; measured precision per level is in bench/results.
const ContextCapPrefix = "capped at low: "
ContextCapPrefix starts the evidence line of a finding capped at low for its local/example context.
const DefaultPasswordEvidence = "" /* 137-byte string literal not displayed */
DefaultPasswordEvidence is the evidence line of a default password reported outside test, example and documentation files.
const DefaultPasswordReason = "default-password-in-test-or-doc"
DefaultPasswordReason is the ledger reason for a one-word default password plus digits (admin123, Welcome@2024) in a test, example or documentation file, where it is dropped. Elsewhere it is reported at low confidence with DefaultPasswordEvidence: production configs really do contain these, and an attacker tries them first.
const FixtureCap = "capped at low: unstructured value in a test/example file"
FixtureCap is the evidence line of a generic value capped at low because it sits in a test/example file.
const UUIDCredentialEvidence = "UUID-shaped value under a credential-named key: kept at low confidence (UUIDs are usually identifiers)"
UUIDCredentialEvidence is the evidence line of a UUID reported because its key names a credential.
const YieldsTag = "http-auth"
YieldsTag marks non-generic rules that still give way to provider rules on the same span: an HTTP Bearer value that is also a JWT or a GitHub token is reported once, by the provider rule.
Variables ¶
var CredentialKey = regexp.MustCompile(`(?i)(?:secret|token|passw|pwd|passphrase|api[_-]?key|apikey|auth(?:orization)?|credential|private[_-]?key|access[_-]?key|key)[a-z0-9_]{0,8}["'\x60]?\s*(?::=|=>|[:=,])\s*["'\x60]?$`)
CredentialKey matches a credential-named key before a value: tokenValue = , "SecretID": , secretVal := , api_key", , Authorization: .
var DefaultIgnoreMarkers = []string{
"secretscan:allow", "gitleaks:allow", "pragma: allowlist secret", "trufflehog:ignore", "nosecret", "noqa: secret",
}
DefaultIgnoreMarkers are recognized inline suppressions from common tools.
var RequestIDKey = regexp.MustCompile(`(?i)(?:(?:request|idempoten|correlation|trace|transaction|session[_-]?id|client[_-]?id|tenant|subscription|object|resource|message|change|sync|csrf|xsrf|nonce|state|lock|lease|revision|etag|continuation|pagination|next|page|cursor|upload|batch|job|order|device|instance|install)[a-z0-9_-]{0,20}|(?:^|[^a-z])[a-z0-9_-]*?(?:id|ids|guid|uuid))["'\x60]?\s*(?::=|=>|[:=,])\s*["'\x60]?$`)
RequestIDKey matches keys whose values are identifiers even when the name contains "token" or "key": request/correlation/idempotency tokens, concurrency and paging tokens (AWS WAF ChangeToken, NextToken, sync tokens, CSRF/state nonces) and any key ending in id (keyId, secret_id). A UUID under such a key is an ID, unlike access_token = <uuid>.
Functions ¶
func Blocks ¶
Blocks reports whether a finding of this confidence blocks under a policy: strict blocks everything; balanced blocks medium and high and lists low (weak evidence, generic values in test/example files) for review. See bench/results for the measured trade-off.
func BlocksFinding ¶
BlocksFinding applies the policy to a finding. testFixtures "block" (the CLI default) makes balanced also block generic values capped at low only for sitting in a test/example file; "review" lists them instead. Provider formats there are high confidence and always block.
Local and example credentials (Context set) never block under balanced: they are listed for review. strict blocks everything.
func ConfidenceRank ¶
ConfidenceRank orders confidence levels; unknown values rank lowest.
func DecodeBasicAuth ¶
DecodeBasicAuth decodes an HTTP Basic credential (base64 of "user:password"). It reports ok only for printable text with a non-empty user and password; random base64 or encoded binary does not qualify.
func EmbeddedReason ¶
EmbeddedReason reports when secret is only a slice of a longer token in line (a digest, commit SHA or base64 payload), the class of false positive where a provider pattern matches inside unrelated data.
func Fingerprint ¶
Fingerprint is gitleaks-compatible: [commit:]file:rule:line.
func IsTestPath ¶
IsTestPath reports whether path looks like test, fixture, example or doc content.
func MeetsSeverity ¶
MeetsSeverity reports whether f is at or above min.
func NoiseReason ¶
NoiseReason applies the same value filters used for generic rules to an arbitrary candidate (e.g. from another scanner's report) and returns why it is noise, or "". Callers must only use it for candidates that are not in a provider-specific format.
func Redact ¶
Redact masks the secret in a finding. pct is the percentage hidden (100 = fully redacted).
func ValidatorNames ¶
func ValidatorNames() []string
ValidatorNames lists the implemented validators (tests check it matches config.Validators).
Types ¶
type Detector ¶
type Detector struct {
// contains filtered or unexported fields
}
Detector applies a ruleset.
type Finding ¶
type Finding struct {
RuleID string `json:"RuleID"`
Description string `json:"Description"`
Severity string `json:"Severity"`
Tags []string `json:"Tags"`
File string `json:"File"`
StartLine int `json:"StartLine"`
EndLine int `json:"EndLine"`
StartColumn int `json:"StartColumn"`
EndColumn int `json:"EndColumn"`
Match string `json:"Match"`
Secret string `json:"Secret"`
Line string `json:"Line,omitempty"`
Entropy float64 `json:"Entropy"`
Decoded string `json:"Decoded,omitempty"` // encoding chain, e.g. "base64"
Commit string `json:"Commit,omitempty"`
Author string `json:"Author,omitempty"`
Email string `json:"Email,omitempty"`
Date string `json:"Date,omitempty"`
Message string `json:"Message,omitempty"`
Fingerprint string `json:"Fingerprint"`
SecretHash string `json:"SecretHash"` // sha256 of the raw secret; stable across redaction
Verification string `json:"Verification,omitempty"`
// Remediation is filled in after detection (rotation, keyless
// alternative, replacement expression); see package remediate.
Remediation *remediate.Guidance `json:"Remediation,omitempty"`
// Confidence (high/medium/low) and the independent evidence behind it.
Confidence string `json:"Confidence"`
Evidence []string `json:"Evidence,omitempty"`
// Blocking is set by the policy: strict blocks every finding, balanced
// blocks high and medium confidence and reports low for review.
Blocking bool `json:"Blocking"`
// Context is "local" (a local/development service: localhost, private
// network, docker-compose, .env.test) or "example" (.env.example and
// other templates). Such findings are capped at low confidence.
Context string `json:"Context,omitempty"`
// Source and Triage are set when re-scoring another scanner's report.
Source string `json:"Source,omitempty"`
Triage string `json:"Triage,omitempty"`
// contains filtered or unexported fields
}
Finding is one detected secret.
type Fragment ¶
type Fragment struct {
Raw string
FilePath string
StartLine int // 1-based line number of the first line of Raw
Commit string
Author string
Email string
Date string
Message string
}
Fragment is a unit of text to scan, with its origin.
type IgnoreSet ¶
type IgnoreSet struct {
// contains filtered or unexported fields
}
IgnoreSet suppresses known findings. It understands:
- gitleaks fingerprints: [commit:]file:rule:line
- sha256:<hex> of a secret (survives line moves and file renames)
- rule:<id> or rule:<id>:<file> (suppress a rule globally or for one file)
func (*IgnoreSet) LoadBaseline ¶
LoadBaseline adds every finding from a previous JSON report.
func (*IgnoreSet) LoadIgnoreFile ¶
LoadIgnoreFile adds entries from an ignore file (.secretscanignore or .gitleaksignore). Missing files are not an error.
type Options ¶
type Options struct {
MaxDecodeDepth int // 0 disables base64/hex/percent decoding
IgnoreMarkers []string // inline markers that suppress a finding on that line
NoNoiseFilters bool // audit mode: disable heuristic false-positive filters
// RecordSuppressed keeps every filtered candidate (not just counts).
RecordSuppressed bool
}
Options tune detection.
type Result ¶
type Result struct {
Findings []Finding
Suppressed []Suppressed // only when Options.RecordSuppressed
Counts map[string]int // suppression reason -> count (always)
}
Result is the outcome of scanning one fragment.
type Suppressed ¶
type Suppressed struct {
RuleID string `json:"RuleID"`
File string `json:"File"`
StartLine int `json:"StartLine"`
Commit string `json:"Commit,omitempty"`
Reason string `json:"Reason"`
Secret string `json:"Secret"`
SecretHash string `json:"SecretHash"`
}
Suppressed is a candidate that matched a rule but was filtered out. The ledger exists so nothing is ever dropped invisibly: counts are always reported and --show-suppressed lists every entry with its reason.