From d4001713a4452b1526119511526ed323b1507321 Mon Sep 17 00:00:00 2001 From: Olsen Budanur Date: Wed, 11 Feb 2026 17:28:19 -0800 Subject: [PATCH] Reduce false positives in codescan and privacy scanner - Amplitude: require SDK-specific patterns (import, init, instance) instead of bare word match. The word "amplitude" is a common math/physics term (e.g. `let amplitude: CGFloat = 8`) and was triggering false positives on variable names and comments. - Placeholder: add ignore patterns for Swift/WidgetKit protocol method signatures like `func placeholder(in context:)` which is a required AppIntentTimelineProvider conformance, not placeholder content. - HTTP URLs: add w3.org, xmlns, DTD, and doctype to the ignore list. XML/SVG namespace URIs (e.g. `http://www.w3.org/2000/svg`) are spec-defined identifiers, not network requests, and are unaffected by App Transport Security. --- internal/codescan/rules.go | 7 ++++++- internal/privacy/scanner.go | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/internal/codescan/rules.go b/internal/codescan/rules.go index 4c829cf..09f35cd 100644 --- a/internal/codescan/rules.go +++ b/internal/codescan/rules.go @@ -95,7 +95,8 @@ func AllRules() []Rule { fix: "Implement ATT prompt before any tracking. Add NSUserTrackingUsageDescription to Info.plist.", languages: []string{"swift", "objc", "typescript", "javascript"}, patterns: []*regexp.Regexp{ - regexp.MustCompile(`(?i)(firebase.*analytics|google.*analytics|facebook.*sdk|fbsdk|adjust.*sdk|appsflyer|amplitude|mixpanel)`), + regexp.MustCompile(`(?i)(firebase.*analytics|google.*analytics|facebook.*sdk|fbsdk|adjust.*sdk|appsflyer|mixpanel)`), + regexp.MustCompile(`(?i)(import\s+Amplitude|AmplitudeSwift|amplitude\.init|Amplitude\.instance|amplitude-js|@amplitude/)`), regexp.MustCompile(`(?i)(import.*@segment/|analytics-react-native|SegmentAnalytics|createClient.*writeKey)`), }, antiPatterns: []*regexp.Regexp{ @@ -182,6 +183,9 @@ func AllRules() []Rule { regexp.MustCompile("(?i)`[^`]*\\b(lorem ipsum|placeholder|coming soon|under construction|todo|tbd)\\b[^`]*`"), regexp.MustCompile(`(?i)\b(lorem ipsum|placeholder|coming soon|under construction|todo|tbd)\b`), // bare text (JSX content) }, + ignorePatterns: []*regexp.Regexp{ + regexp.MustCompile(`(?i)(func\s+placeholder\s*\(|\.placeholder\s*[:=]|placeholder\s*[:=]\s*[A-Z]|placeholder\s*\(in\s*context)`), // Swift/WidgetKit protocol methods and property assignments + }, }, &PatternRule{ id: "console-log", @@ -225,6 +229,7 @@ func AllRules() []Rule { }, ignorePatterns: []*regexp.Regexp{ regexp.MustCompile(`(?i)(localhost|127\.0\.0\.1|0\.0\.0\.0|http://example)`), + regexp.MustCompile(`(?i)(w3\.org|xmlns|DTD|doctype)`), // XML/SVG namespace URIs and DTD references are identifiers, not network requests }, }, &PatternRule{ diff --git a/internal/privacy/scanner.go b/internal/privacy/scanner.go index f03bcc3..816e825 100644 --- a/internal/privacy/scanner.go +++ b/internal/privacy/scanner.go @@ -103,7 +103,7 @@ var trackingSDKPatterns = []struct { {regexp.MustCompile(`(?i)(fbsdk|facebook.*sdk)`), "Facebook SDK"}, {regexp.MustCompile(`(?i)adjust.*sdk`), "Adjust SDK"}, {regexp.MustCompile(`(?i)appsflyer`), "AppsFlyer"}, - {regexp.MustCompile(`(?i)(amplitude)`), "Amplitude"}, + {regexp.MustCompile(`(?i)(import\s+Amplitude|AmplitudeSwift|amplitude\.init|Amplitude\.instance|amplitude-js|@amplitude/)`), "Amplitude"}, {regexp.MustCompile(`(?i)(mixpanel)`), "Mixpanel"}, {regexp.MustCompile(`(?i)(@segment/|analytics-react-native)`), "Segment"}, {regexp.MustCompile(`(?i)(branch\.io|react-native-branch)`), "Branch"},