Skip to content

Commit 05ea2eb

Browse files
committed
feat(security): add CX-SEC-008 sensitive data in logs detector
1 parent 81a674a commit 05ea2eb

1 file changed

Lines changed: 78 additions & 0 deletions

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package detectors
2+
3+
import (
4+
"strings"
5+
6+
"github.com/hamza-hafeez82/cortex/internal/parser"
7+
"github.com/hamza-hafeez82/cortex/pkg/detector"
8+
)
9+
10+
type SensitiveDataInLogsDetector struct{}
11+
12+
func (d *SensitiveDataInLogsDetector) ID() string { return "CX-SEC-008" }
13+
func (d *SensitiveDataInLogsDetector) Name() string { return "Sensitive Data in Logs" }
14+
func (d *SensitiveDataInLogsDetector) Category() string { return detector.CategorySecurity }
15+
func (d *SensitiveDataInLogsDetector) Severity() string { return detector.SeverityMedium }
16+
17+
var logFunctions = []string{
18+
"console.log(", "console.error(", "console.warn(", "console.debug(",
19+
"fmt.Println(", "fmt.Printf(", "fmt.Print(", "log.Println(", "log.Printf(", "log.Print(",
20+
"log.Fatal(", "log.Fatalf(", "logger.info(", "logger.debug(", "logger.error(", "logger.warn(",
21+
"print(", "logging.info(", "logging.debug(", "logging.warning(", "logging.error(",
22+
"System.out.println(", "System.err.println(",
23+
}
24+
25+
var sensitiveDataKeywords = []string{
26+
"password", "passwd", "secret", "token", "api_key", "apikey",
27+
"private_key", "credit_card", "cvv", "ssn", "social_security",
28+
"auth", "authorization", "bearer", "jwt", "session",
29+
}
30+
31+
func (d *SensitiveDataInLogsDetector) Run(ctx *detector.ScanContext) []detector.Issue {
32+
var issues []detector.Issue
33+
34+
for _, f := range ctx.Repo.Files {
35+
if !parser.IsSourceLanguage(f.Language) || len(f.Lines) == 0 {
36+
continue
37+
}
38+
sc := parser.NewScanner(f.Path, f.Lines)
39+
40+
for i, line := range f.Lines {
41+
trimmed := strings.TrimSpace(line)
42+
if parser.IsComment(trimmed, f.Language) {
43+
continue
44+
}
45+
46+
hasLogFn := false
47+
for _, fn := range logFunctions {
48+
if strings.Contains(trimmed, fn) {
49+
hasLogFn = true
50+
break
51+
}
52+
}
53+
if !hasLogFn {
54+
continue
55+
}
56+
57+
lineLower := strings.ToLower(trimmed)
58+
for _, kw := range sensitiveDataKeywords {
59+
if strings.Contains(lineLower, kw) {
60+
issues = append(issues, detector.Issue{
61+
Code: d.ID(),
62+
Title: d.Name(),
63+
Message: "Sensitive field '" + kw + "' may be written to logs — redact sensitive data before logging",
64+
File: f.Path,
65+
Line: i + 1,
66+
Severity: d.Severity(),
67+
Confidence: detector.ConfidenceMedium,
68+
Category: d.Category(),
69+
Snippet: trimmed,
70+
Context: sc.Context(i+1, 3),
71+
})
72+
break
73+
}
74+
}
75+
}
76+
}
77+
return issues
78+
}

0 commit comments

Comments
 (0)