Skip to main content

vibekit_proxy/
redaction.rs

1use regex::Regex;
2
3pub struct RedactionEngine {
4    patterns: Vec<Regex>,
5}
6
7impl RedactionEngine {
8    pub fn new() -> Self {
9        Self {
10            patterns: initialize_sensitive_patterns(),
11        }
12    }
13
14    pub fn redact_sensitive_content(&self, content: &str) -> String {
15        let mut redacted_content = content.to_string();
16        
17        for pattern in &self.patterns {
18            redacted_content = pattern.replace_all(&redacted_content, "REDACTED").to_string();
19        }
20        
21        redacted_content
22    }
23}
24
25impl Default for RedactionEngine {
26    fn default() -> Self {
27        Self::new()
28    }
29}
30
31fn initialize_sensitive_patterns() -> Vec<Regex> {
32    let patterns = vec![
33        // ==== OPENAI & AI PROVIDERS ====
34        r"sk-proj-[A-Za-z0-9_-]+",                // OpenAI project-scoped key
35        r"dtn_[A-Za-z0-9_]+",                     // Daytona API key
36        r"e2b_[A-Za-z0-9_]+",                     // E2B API key
37        r"sk-ant-[A-Za-z0-9_-]+",                 // Anthropic API key
38        r"sk-or-[A-Za-z0-9_-]+",                  // OpenAI org-scoped key
39        r"sk-[A-Za-z0-9_-]+",                     // OpenAI generic secret
40        r"gsk_[A-Za-z0-9_-]+",                    // Google Generative AI Studio key
41        r"xai-[A-Za-z0-9_-]+",                    // xAI key
42
43        // ==== GITHUB ====
44        r"ghp_[A-Za-z0-9_]{36}",                      // GitHub PAT (classic)
45        r"gho_[A-Za-z0-9_]{36}",                      // GitHub OAuth token
46        r"ghs_[A-Za-z0-9_]{36}",                      // GitHub App server-to-server
47        r"ghu_[A-Za-z0-9_]{36}",                      // GitHub App user-to-server
48        r"ghr_[A-Za-z0-9_]{36}",                      // GitHub refresh token
49        r"github_pat_[A-Za-z0-9_]{22}_[A-Za-z0-9_]{59}", // GitHub fine-grained PAT
50
51        // ==== GITLAB ====
52        r"glpat-[A-Za-z0-9_-]+",                  // GitLab PAT
53
54        // ==== AWS ====
55        r"AKIA[0-9A-Z]{16}",                          // AWS access key ID (long-lived)
56        r"ASIA[0-9A-Z]{16}",                          // AWS temporary access key ID
57        r"(?i)(aws_)?secret(access)?(_)?key\s*[:=]\s*[A-Za-z0-9/+=]{35,}", // AWS secret key
58
59        // ==== GOOGLE API KEYS ====
60        r"AIza[0-9A-Za-z-_]{35}",                     // Google API key (common AIza prefix)
61        r"ya29\.[0-9A-Za-z-_]+",                      // Google OAuth access token
62        r"GOCSPX-[A-Za-z0-9-_]+",                 // Google OAuth client secret
63
64        // ==== SLACK ====
65        r"xoxb-[A-Za-z0-9-]+-[A-Za-z0-9-]+-[A-Za-z0-9-]+", // Slack bot token
66        r"xoxp-[A-Za-z0-9-]+-[A-Za-z0-9-]+-[A-Za-z0-9-]+", // Slack user token
67        r"xoxa-[A-Za-z0-9-]+-[A-Za-z0-9-]+-[A-Za-z0-9-]+", // Slack workspace token
68        r"xapp-1-[A-Z0-9-]+-[0-9]+-[A-Za-z0-9]+",          // Slack App level token
69
70        // ==== STRIPE ====
71        r"sk_live_[0-9a-zA-Z]+",                  // Stripe live secret key
72        r"sk_test_[0-9a-zA-Z]+",                  // Stripe test secret key
73        r"rk_live_[0-9a-zA-Z]+",                  // Stripe restricted key live
74        r"rk_test_[0-9a-zA-Z]+",                  // Stripe restricted key test
75        r"whsec_[A-Za-z0-9]+",                    // Stripe webhook secret
76
77        // ==== TWILIO ====
78        r"AC[0-9a-fA-F]{32}",                         // Twilio Account SID
79        r"SK[0-9a-fA-F]{32}",                         // Twilio API Key SID
80
81        // ==== SENDGRID / MAIL PROVIDERS ====
82        r"SG\.[A-Za-z0-9_\-\.]{66}",                  // SendGrid API key
83        r"key-[0-9a-f]{32}",                          // Mailgun API key (specific with 'key-' prefix)
84        r"xkeysib-[A-Za-z0-9]{64}-[A-Za-z0-9]{16}",   // SendInBlue API key
85
86        // ==== PAYMENT / CREDIT CARDS ====
87        r"\b4[0-9]{12}(?:[0-9]{3})?\b",               // Visa (no spaces)
88        r"\b4[0-9]{3}[\s-]?[0-9]{4}[\s-]?[0-9]{4}[\s-]?[0-9]{4}\b", // Visa (with spaces/dashes)
89        r"\b5[1-5][0-9]{14}\b",                       // MasterCard (no spaces)
90        r"\b5[1-5][0-9]{2}[\s-]?[0-9]{4}[\s-]?[0-9]{4}[\s-]?[0-9]{4}\b", // MasterCard (with spaces/dashes)
91        r"\b3[47][0-9]{13}\b",                        // AmEx (no spaces)
92        r"\b3[47][0-9]{2}[\s-]?[0-9]{6}[\s-]?[0-9]{5}\b", // AmEx (with spaces/dashes)
93        r"\b6(?:011|5[0-9]{2})[0-9]{12}\b",           // Discover (no spaces)
94        r"\b6(?:011|5[0-9]{2})[\s-]?[0-9]{4}[\s-]?[0-9]{4}[\s-]?[0-9]{4}\b", // Discover (with spaces/dashes)
95
96        // ==== EMAIL ADDRESSES ====
97        r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b", // Email addresses
98
99        // ==== DATABASE CONNECTION STRINGS - With passwords ====
100        r"\bpostgres(?:ql)?://[A-Za-z0-9_%+.-]+:[^@\s]{1,}@[^\s]+/[A-Za-z0-9_.-]+",
101        r"\bmongodb(?:\+srv)?://[A-Za-z0-9_%+.-]+:[^@\s]{1,}@[^\s]+/[A-Za-z0-9_.-]+",
102        r"\bmysql://[A-Za-z0-9_%+.-]+:[^@\s]{1,}@[^\s]+/[A-Za-z0-9_.-]+",
103        r"\bredis://[A-Za-z0-9_%+.-]+:[^@\s]{1,}@[A-Za-z0-9_.:-]+",
104
105        // ==== JWT TOKENS ====
106        r"\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b", // JWT tokens
107
108        // ==== SSH KEYS ====
109        r"-----BEGIN (?:RSA|DSA|EC|OPENSSH) PRIVATE KEY-----[\s\S]+?-----END (?:RSA|DSA|EC|OPENSSH) PRIVATE KEY-----",
110
111        // ==== OTHER SPECIFIC API KEYS ====
112        r"\bDD_API_KEY\b[^\n]{0,40}[:=]\s*[0-9a-f]{32}\b",         // Datadog
113        r"\bDD_APP_KEY\b[^\n]{0,40}[:=]\s*[0-9a-f]{40}\b",         // Datadog
114        r"NRAK-[A-Z0-9]{27}",                                        // New Relic ingest key
115        r"NRAL-[A-Z0-9]{27}",                                        // New Relic license key
116        r"shpat_[a-f0-9]{32}",                                       // Shopify private app access token
117        r"shpss_[a-f0-9]{32}",                                       // Shopify shared secret
118        r"npm_[A-Za-z0-9]{36}",                                      // npm access token
119        r"\bpypi-AgENdGV\w{20,}\b",                                 // PyPI token
120        r"EAA[A-Za-z0-9]+",                                      // Facebook access token
121        r"\bBearer\s+AAAAAAAA[A-Za-z0-9%\-_]+\b",                 // Twitter bearer token
122        r"lin_[A-Za-z0-9]{40}",                                      // Linear API key
123        r"secret_[A-Za-z0-9]{43}",                                   // Notion token
124        r"CFPAT-[A-Za-z0-9_-]+",                                // Contentful API token
125        r"sdk-[A-Za-z0-9_-]+",                                  // LaunchDarkly SDK key (made more specific)
126        r"mob-[A-Za-z0-9_-]+",                                  // LaunchDarkly Mobile key (made more specific)
127        r"r8_[A-Za-z0-9]+",                                      // Replicate API token
128
129        // ==== CRYPTO WALLETS ====
130        r"\b0x[a-fA-F0-9]{40}\b",                                    // Ethereum address
131        r"\b[13][a-km-zA-HJ-NP-Z1-9]{25,34}\b",                     // Bitcoin (legacy)
132        r"\bbc1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{11,71}\b",       // Bitcoin Bech32
133
134        // ==== SPECIFIC SECRET PATTERNS WITH CONTEXT ====
135        r"(?i)\b(SECRET_KEY|API_SECRET|CLIENT_SECRET|PRIVATE_KEY)\b\s*[:=]\s*[A-Za-z0-9\-_.+/=]+",
136        r"(?i)\b(password|passwd|pwd)\b\s*[:=]\s*[^\s]+",
137        r"(?i)\b(api_key|apikey|api_token|access_token)\b\s*[:=]\s*[A-Za-z0-9\-_.]+",
138    ];
139
140    patterns.into_iter()
141        .filter_map(|pattern| Regex::new(pattern).ok())
142        .collect()
143}