fix(postgres): honor ignore tags for default port URLs (#4968)

* fix(postgres): honor ignore tags for default port URLs

* test(postgres): add raw vs primary secret test and document design decision
This commit is contained in:
Chethas Dileep
2026-06-05 18:17:44 +05:00
committed by GitHub
parent 90a3efa36b
commit 75add79b92
3 changed files with 45 additions and 5 deletions
+19 -5
View File
@@ -58,6 +58,11 @@ type Scanner struct {
ignorePatterns []*regexp.Regexp
}
type uriMatch struct {
params map[string]string
rawURI string
}
func New(opts ...func(*Scanner)) *Scanner {
scanner := &Scanner{
ignorePatterns: []*regexp.Regexp{},
@@ -93,12 +98,13 @@ func (s Scanner) Keywords() []string {
func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) ([]detectors.Result, error) {
var results []detectors.Result
candidateParamSets := findUriMatches(data, s.ignorePatterns)
candidateURIs := findUriMatches(data, s.ignorePatterns)
for _, params := range candidateParamSets {
for _, candidateURI := range candidateURIs {
if common.IsDone(ctx) {
break
}
params := candidateURI.params
user, ok := params[pgUser]
if !ok {
continue
@@ -141,6 +147,11 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) ([]dete
RawV2: raw,
SecretParts: map[string]string{"connection_string": string(raw)},
}
// Set the un-normalized raw match as the primary secret value.
// This ensures that the engine's line-offset and ignore-tag matching logic
// (which searches the source document for the exact string) can locate the match,
// even though Raw/RawV2 are stored in a normalized form.
result.SetPrimarySecretValue(candidateURI.rawURI)
// We don't need to normalize the (deprecated) requiressl option into the (up-to-date) sslmode option - pq can
// do it for us - but we will do it anyway here so that when we later capture sslmode into ExtraData we will
@@ -199,8 +210,8 @@ func (s Scanner) IsFalsePositive(_ detectors.Result) (bool, string) {
return false, ""
}
func findUriMatches(data []byte, ignorePatterns []*regexp.Regexp) []map[string]string {
var matches []map[string]string
func findUriMatches(data []byte, ignorePatterns []*regexp.Regexp) []uriMatch {
var matches []uriMatch
for _, uri := range uriPattern.FindAll(data, -1) {
if shouldIgnore(uri, ignorePatterns) {
continue
@@ -224,7 +235,10 @@ func findUriMatches(data []byte, ignorePatterns []*regexp.Regexp) []map[string]s
}
params[pgDbType] = dbType
matches = append(matches, params)
matches = append(matches, uriMatch{
params: params,
rawURI: string(uri),
})
}
return matches
}
+14
View File
@@ -139,3 +139,17 @@ func TestPostgres_FromDataWithIgnorePattern(t *testing.T) {
require.NoError(t, err)
assert.Empty(t, got)
}
func TestPostgres_RawVsPrimarySecret(t *testing.T) {
s := Scanner{}
input := "postgres://user:pass@host/dbname"
results, err := s.FromData(context.Background(), false, []byte(input))
require.NoError(t, err)
require.Len(t, results, 1)
res := results[0]
expectedRaw := "postgres://user:pass@host:5432"
assert.Equal(t, expectedRaw, string(res.Raw))
assert.Equal(t, expectedRaw, string(res.RawV2))
assert.Equal(t, input, res.GetPrimarySecretValue())
}
+12
View File
@@ -1508,6 +1508,18 @@ def test_something():
assert connection_string == "postgres://master_user:master_password@hostname:1234/main" # trufflehog:ignore`,
expectedFindings: 0,
},
{
name: "ignore postgres url without explicit port",
content: `
# tests/example_false_positive.py
def test_something():
connection_string = "who-cares"
# The detector normalizes this URL to include :5432, but the ignore tag should still be honored.
assert connection_string == "postgres://master_user:master_password@hostname/main" # trufflehog:ignore`,
expectedFindings: 0,
},
{
name: "ignore not on secret line",
content: `