-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathSecretSifter_Desktop_User_Documentation_v1.7.6.html
More file actions
734 lines (637 loc) · 50.3 KB
/
Copy pathSecretSifter_Desktop_User_Documentation_v1.7.6.html
File metadata and controls
734 lines (637 loc) · 50.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SecretSifter Desktop — User Documentation v1.7.6</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
:root {
--orange: #E8561E; --navy: #1a3a5c; --navy2: #0d2847;
--bg: #fff; --codebg: #f4f4f4; --border: #e0e0e0;
--text: #1a1a1a; --muted: #555; --green: #1e8449;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: 'Inter', Arial, sans-serif; color: var(--text); font-size: 13.5px; line-height: 1.65; }
.cover { page-break-after: always; background: linear-gradient(155deg,#1a3a5c,#091e36);
color:#fff; display:flex; flex-direction:column; height:297mm; }
.cover-stripe { height:7px; background:linear-gradient(90deg,#E8561E,#f07a30); }
.cover-body { flex:1; display:flex; flex-direction:column; justify-content:center; padding:64px 80px; }
.cover-icon { width:96px; height:96px; border-radius:22px; margin-bottom:36px;
background:linear-gradient(135deg,#E8561E,#c44a18); display:flex; align-items:center; justify-content:center;
font-size:54px; font-weight:800; color:#fff; }
.cover-title { font-size:54px; font-weight:800; color:#fff; letter-spacing:-2px; line-height:1.0; margin-bottom:6px; }
.cover-title .accent { color:#E8561E; }
.cover-bar { width:72px; height:5px; background:#E8561E; border-radius:3px; margin:20px 0; }
.cover-sub { font-size:18px; color:#a8c4e0; font-weight:300; margin-bottom:24px; }
.cover-desc { font-size:13.5px; color:#c0d8ee; max-width:560px; line-height:1.8;
border-left:3px solid #E8561E; padding-left:16px; }
.cover-footer { border-top:1px solid rgba(255,255,255,.12); padding:18px 80px;
display:grid; grid-template-columns:repeat(4,1fr); font-size:11px; color:#7aa0c0; }
.cover-footer strong { color:#a8c4e0; display:block; font-size:9.5px;
text-transform:uppercase; letter-spacing:.8px; margin-bottom:2px; }
.toc { page-break-after:always; padding:52px 72px; }
.toc h2 { color:var(--navy); font-size:26px; margin-bottom:22px;
border-bottom:3px solid var(--orange); padding-bottom:8px; }
.toc ol { list-style:none; }
.toc > ol > li { font-size:14px; font-weight:600; margin:9px 0 3px; color:var(--navy); }
.toc > ol > li > a { color:var(--navy); text-decoration:none; }
.toc > ol > li > ol > li { font-size:12px; font-weight:400; color:var(--muted);
margin:2px 0 2px 26px; }
.toc > ol > li > ol > li > a { color:var(--muted); text-decoration:none; }
.toc-n { display:inline-block; min-width:26px; color:var(--orange); font-weight:700; }
@page { margin:16mm 16mm 20mm 16mm; }
.content { padding:48px 64px; max-width:980px; margin:0 auto; }
h1 { font-size:28px; font-weight:700; color:var(--navy);
border-bottom:3px solid var(--orange); padding-bottom:8px;
margin:0 0 16px; page-break-before:always; }
h1:first-child { page-break-before:avoid; }
h2 { font-size:19px; font-weight:600; color:var(--navy);
margin:30px 0 10px; border-bottom:1px solid var(--border); padding-bottom:3px; }
h3 { font-size:15px; font-weight:600; color:var(--orange); margin:22px 0 7px; }
h4 { font-size:13.5px; font-weight:600; color:#333; margin:16px 0 5px; }
.lead { font-size:14px; color:var(--muted); margin:-4px 0 18px;
padding-bottom:12px; border-bottom:1px solid var(--border); }
p { margin-bottom:11px; }
ul,ol { margin:7px 0 14px 26px; }
li { margin-bottom:4px; }
table { width:100%; border-collapse:collapse; margin:12px 0 20px; font-size:12.5px; }
th { background:var(--navy); color:#fff; padding:8px 12px; text-align:left;
font-weight:600; font-size:11.5px; letter-spacing:.3px; }
td { padding:7px 12px; border-bottom:1px solid var(--border); vertical-align:top; }
tr:nth-child(even) td { background:#f8fafc; }
code { background:var(--codebg); padding:1px 5px; border-radius:3px;
font-family:'JetBrains Mono','Menlo',monospace; font-size:11.5px; color:#c0392b; }
pre { background:#1e1e2e; color:#cdd6f4; padding:15px 18px; border-radius:6px;
font-family:'JetBrains Mono','Menlo',monospace; font-size:11.5px;
margin:10px 0 18px; border-left:4px solid var(--orange);
white-space:pre-wrap; overflow-x:auto; }
pre .c { color:#6272a4; } pre .kw { color:#89b4fa; } pre .s { color:#a6e3a1; }
.note { background:#fff8f0; border-left:4px solid var(--orange);
padding:11px 16px; border-radius:0 5px 5px 0; margin:14px 0; font-size:13px; }
.info { background:#f0f6ff; border-left-color:var(--navy); }
.warn { background:#fff3e0; border-left-color:#f57c00; }
.ok { background:#f0faf5; border-left-color:#1e8449; }
.badge { display:inline-block; padding:1px 8px; border-radius:10px; font-size:11px; font-weight:600; }
.b-r { background:#fde8e8; color:#c0392b; } .b-o { background:#fef3e2; color:#d35400; }
.b-b { background:#e8f4fd; color:#2471a3; } .b-g { background:#f0f0f0; color:#555; }
.b-y { background:#fff8d4; color:#7d6608; } .b-v { background:#f5f0ff; color:#6c3483; }
.feature-grid { display:grid; grid-template-columns:1fr 1fr; gap:14px; margin:18px 0; }
.feature-box { border:1px solid var(--border); border-radius:6px; padding:14px 16px;
background:#fafafa; }
.feature-box strong { color:var(--orange); display:block; margin-bottom:6px; font-size:13px; }
.feature-box p { font-size:12.5px; color:var(--muted); }
@media print {
.cover { height:297mm; } .toc { page-break-after:always; }
h1 { page-break-before:always; } h1:first-child { page-break-before:avoid; }
h2 { page-break-after:avoid; } h3 { page-break-after:avoid; }
table,figure,pre { page-break-inside:avoid; }
}
</style>
</head>
<body>
<!-- ═════════════════════════════════════════ COVER ═════════════════════════════════════════ -->
<div class="cover">
<div class="cover-stripe"></div>
<div class="cover-body">
<div class="cover-icon">SS</div>
<div class="cover-title">Secret<span class="accent">Sifter</span></div>
<div class="cover-bar"></div>
<div class="cover-sub">Desktop Edition — User Documentation</div>
<div class="cover-desc">
End-user guide for the Windows desktop edition of SecretSifter — a standalone
credentials and secrets scanner that combines bulk URL scanning, an embedded
MITM proxy, a Playwright-driven crawler, HAR file import, and AI-ready REST &
MCP automation in a single jpackage installer. This document covers installation,
every workflow, the settings catalog, triage guidance, the REST API contract,
troubleshooting, and migration notes for analysts moving over from the
Burp extension edition.
</div>
</div>
<div class="cover-footer">
<div><strong>Version</strong>1.7.6</div>
<div><strong>Edition</strong>Windows Desktop (Standalone)</div>
<div><strong>Generated</strong>2026-04-25</div>
<div><strong>Audience</strong>Security Analysts</div>
</div>
</div>
<!-- ═════════════════════════════════════════ TOC ═════════════════════════════════════════ -->
<div class="toc">
<h2>Contents</h2>
<ol>
<li><span class="toc-n">1.</span><a href="#exec-summary">Executive Summary</a></li>
<li><span class="toc-n">2.</span><a href="#problems">Problems SecretSifter Solves</a></li>
<li><span class="toc-n">3.</span><a href="#features">Features Overview</a></li>
<li><span class="toc-n">4.</span><a href="#install">Installation & First Run</a></li>
<li><span class="toc-n">5.</span><a href="#usage">Usage Guide</a></li>
<li><span class="toc-n">6.</span><a href="#detection">Detection Engine Deep Dive</a></li>
<li><span class="toc-n">7.</span><a href="#severity">Severity & Confidence Model</a></li>
<li><span class="toc-n">8.</span><a href="#triage">Triage Guide & FP Determination</a></li>
<li><span class="toc-n">9.</span><a href="#settings">Settings Reference</a></li>
<li><span class="toc-n">10.</span><a href="#rest">REST API & MCP Quickstart</a></li>
<li><span class="toc-n">11.</span><a href="#exports">Reports & Exports</a></li>
<li><span class="toc-n">12.</span><a href="#troubleshooting">Troubleshooting</a></li>
<li><span class="toc-n">13.</span><a href="#requirements">Requirements & Compatibility</a></li>
<li><span class="toc-n">14.</span><a href="#building">Building from Source</a></li>
<li><span class="toc-n">15.</span><a href="#credits">Credits & License</a></li>
</ol>
</div>
<div class="content">
<!-- ═════════════════════════════════ 1. EXEC SUMMARY ═════════════════════════════════ -->
<h1 id="exec-summary">1. Executive Summary</h1>
<p class="lead">SecretSifter Desktop is a Windows-native, single-installer secret scanner for live web applications. It ships with the same detection engine as the Burp extension edition, plus a Playwright-driven crawler, MITM proxy, and an automation API — no Burp license required.</p>
<p>The tool is designed for security analysts who need to discover hard-coded credentials in modern single-page applications, API responses, request headers, and proxied traffic. It does not require the analyst to be running a paid web-proxy product. Findings appear in a Burp-style dashboard with severity badges, sortable columns, and a Details / Request / Response side panel for each finding.</p>
<h2>What's New in v1.7.6</h2>
<ul>
<li>Mask Value / Mask URL fixed (now reliably masks the right column even after column reordering).</li>
<li>Start Scan auto-clears prior results and dedup state — no more stale findings bleeding into a fresh run.</li>
<li>Compact 📋 copy icons in the Details panel free up screen real estate for long URLs.</li>
<li>Center divider has hard min-widths so dragging can no longer hide either pane.</li>
<li>New AI Provider API Key field (Anthropic / OpenAI / etc.) with masked input and 👁 reveal toggle, persisted to local user prefs.</li>
</ul>
<!-- ═════════════════════════════════ 2. PROBLEMS ═════════════════════════════════ -->
<h1 id="problems">2. Problems SecretSifter Solves</h1>
<p class="lead">Modern web apps leak credentials in places traditional scanners miss. SecretSifter targets these specifically.</p>
<table>
<tr><th>Problem</th><th>SecretSifter's answer</th></tr>
<tr><td>Burp licenses are expensive and not every analyst on a team has one</td><td>Free standalone Windows installer; no Burp dependency</td></tr>
<tr><td>API keys hardcoded in 2–8 MB Angular / React bundles</td><td>GENERIC_KV scanner runs on the full text — no truncation — with line-aware reporting that mirrors Burp's per-line output</td></tr>
<tr><td>Vendor-specific tokens (Azure subscription keys, AWS keys, JWTs, Google API keys, Stripe, Slack, GitHub, etc.)</td><td>100+ anchored vendor rules, each emitting CERTAIN-confidence findings</td></tr>
<tr><td>Secrets in OAuth-style form-encoded responses (<code>access_token=...&resource=...</code>)</td><td>Form-encoded pre-pass extracts each <code>key=value</code> pair</td></tr>
<tr><td>Secrets in <code>__NEXT_DATA__</code> / <code>__INITIAL_STATE__</code> SSR blobs</td><td>JSON_SCRIPT_TAG + SSR-state-blob scanners</td></tr>
<tr><td>Secrets buried in deep JSON responses (<code>data.user.config.apiKey</code>)</td><td>JSON_WALK recursive walker</td></tr>
<tr><td>SPA-loaded resources that bulk fetch can't see</td><td>Built-in Playwright crawler (real Chrome via channel for WAF bypass)</td></tr>
<tr><td>WAF-blocked corporate WiFi that flags headless browsers</td><td>Crawler launches real Google Chrome (channel) plus <code>--disable-blink-features=AutomationControlled</code></td></tr>
<tr><td>Need to capture request / response details for each finding</td><td>Burp-style Details panel with Request and Response tabs, populated by the capture store</td></tr>
<tr><td>Custom org-specific rule packs without scanner noise</td><td>"Use custom rules ONLY" toggle with <em>raw mode</em> — bypasses every default noise filter</td></tr>
<tr><td>Need to integrate scanner output into automated pipelines</td><td>Bearer-authenticated REST API + JSON-RPC MCP server on localhost</td></tr>
<tr><td>Need to share findings with stakeholders</td><td>Single-click All-in-One ZIP bundle (HTML + CSV + JSON + suppressed CSV), per-domain ZIP, all timestamped</td></tr>
</table>
<!-- ═════════════════════════════════ 3. FEATURES ═════════════════════════════════ -->
<h1 id="features">3. Features Overview</h1>
<div class="feature-grid">
<div class="feature-box"><strong>Bulk URL Scan</strong><p>Paste a list of URLs, optionally enable Playwright browser-mode for SPAs. Each URL is fetched (with auth-failure detection), all referenced JS bundles are followed, and every response body is run through the full detection pipeline.</p></div>
<div class="feature-box"><strong>Playwright Crawler</strong><p>Drives real Google Chrome (auto-detected) via a stealth-flagged Playwright session. Captures every request and response, follows in-app navigation, discovers SPA-loaded resources that bulk fetch alone misses.</p></div>
<div class="feature-box"><strong>MITM Proxy</strong><p>Embedded HTTP/1.1 proxy with on-the-fly per-host TLS certificates (Bouncy Castle CA). Point any browser at <code>127.0.0.1:8888</code>, import the exported CA, and inflight traffic is scanned and surfaced as findings.</p></div>
<div class="feature-box"><strong>HAR Import</strong><p>Replay any browser DevTools HAR file through the scanner. All requests + responses are restored to the capture store as if the proxy had captured them, so the Details panel works the same way.</p></div>
<div class="feature-box"><strong>Findings Dashboard</strong><p>Sortable / filterable table with severity badges, NOISE triage state, mask-value / mask-URL toggles, column visibility menu, and a Burp-style Details / Request / Response side panel.</p></div>
<div class="feature-box"><strong>Custom Rules</strong><p>User-defined regex rules (<code>RuleName | regex | severity</code>). Run additively with built-in detection, or in <em>raw mode</em> alongside the "Use ONLY" toggle that bypasses every default noise filter.</p></div>
<div class="feature-box"><strong>Reports & Exports</strong><p>All-in-One Report ZIP (HTML + CSV + JSON + suppressed CSV) and Per-Domain Reports ZIP. Every artifact timestamped <code>yyyyMMdd_HHmmss</code>. CSV columns match the HTML report.</p></div>
<div class="feature-box"><strong>REST API + MCP</strong><p>Bearer-authenticated JSON-RPC + REST server on localhost. Lets Claude Desktop / Claude Code CLI / curl / Python automate scans, fetch findings, update settings.</p></div>
</div>
<h2>Detection Rule Counts</h2>
<table>
<tr><th>Family</th><th>Rules</th><th>Confidence</th></tr>
<tr><td>Anchored vendor tokens (AWS, Azure, GCP, Stripe, GitHub, Slack, JWT, etc.)</td><td>100+</td><td>CERTAIN</td></tr>
<tr><td>Context-gated rules (DB connection strings, OAuth flows, headers)</td><td>40+</td><td>FIRM</td></tr>
<tr><td>GENERIC_KV (semantic key + entropy gate)</td><td>1 (with rich filter chain)</td><td>FIRM / CERTAIN</td></tr>
<tr><td>JSON_WALK (recursive deep-key walker)</td><td>1</td><td>FIRM</td></tr>
<tr><td>Entropy-gated unanchored tokens</td><td>1</td><td>FIRM</td></tr>
<tr><td>Getter-function returns (JS only)</td><td>1</td><td>FIRM</td></tr>
<tr><td>SSR state blob recursion</td><td>1</td><td>varies</td></tr>
<tr><td>User-defined custom rules</td><td>unbounded</td><td>FIRM (or NOISE in raw mode)</td></tr>
</table>
<h2>Scan Tiers</h2>
<table>
<tr><th>Tier</th><th>Speed</th><th>What's included</th></tr>
<tr><td><span class="badge b-r">FAST</span></td><td>Fastest</td><td>Vendor tokens + URL credentials + custom rules</td></tr>
<tr><td><span class="badge b-y">LIGHT</span></td><td>Medium</td><td>FAST + DB connection strings + context-gated rules</td></tr>
<tr><td><span class="badge b-b">FULL</span></td><td>Thorough</td><td>LIGHT + GENERIC_KV (full text) + SSR blobs + entropy + getter functions</td></tr>
</table>
<!-- ═════════════════════════════════ 4. INSTALL ═════════════════════════════════ -->
<h1 id="install">4. Installation & First Run</h1>
<h2>4.1 Prerequisites</h2>
<table>
<tr><th>Component</th><th>Required</th><th>Notes</th></tr>
<tr><td>Windows 10 / 11</td><td>✓</td><td>x64</td></tr>
<tr><td>Java Runtime</td><td>—</td><td>Bundled inside the installer (jpackage)</td></tr>
<tr><td>Google Chrome</td><td>Recommended</td><td>Used by the crawler for WAF-bypass; falls back to bundled Chromium / system Edge if Chrome absent</td></tr>
<tr><td>Disk space</td><td>~500 MB</td><td>Installer + bundled JRE + Chromium</td></tr>
<tr><td>Admin rights</td><td>—</td><td>Per-user install; no admin required</td></tr>
</table>
<h2>4.2 Install</h2>
<ol>
<li>Download <code>SecretSifter-1.7.6.exe</code>.</li>
<li>Double-click. Windows SmartScreen may warn — click <em>More info → Run anyway</em>.</li>
<li>Follow the installer prompts. Default install path is <code>%LOCALAPPDATA%\SecretSifter</code>.</li>
<li>The installer creates a Start Menu shortcut and (optional) Desktop icon.</li>
</ol>
<h2>4.3 First Run</h2>
<p>On first launch, SecretSifter:</p>
<ul>
<li>Generates a random MCP port (8000–9000 range) and a 32-hex Bearer token. Both visible in <strong>Settings → AI / MCP</strong>.</li>
<li>Defaults to FULL tier scanning, entropy threshold 3.5, PII detection enabled, request-header scanning enabled.</li>
<li>Loads the default key blocklist (<code>STORAGE_KEY_</code>, <code>STATE_KEY_</code>, <code>NEXT_PUBLIC_</code>, <code>REACT_APP_PUBLIC_</code>, <code>VUE_APP_PUBLIC_</code>).</li>
<li>Settings persisted to the Windows registry under <code>HKCU\Software\JavaSoft\Prefs\com\secretsifter</code>.</li>
</ul>
<!-- ═════════════════════════════════ 5. USAGE ═════════════════════════════════ -->
<h1 id="usage">5. Usage Guide</h1>
<h2>5.1 Bulk URL Scan</h2>
<ol>
<li>Open the <strong>Scan</strong> tab.</li>
<li>Paste one URL per line into the <em>Target URLs</em> area.</li>
<li>(Optional) Enable <em>Browser Mode</em> for Playwright crawling — captures SPA-loaded resources.</li>
<li>Set <em>Threads</em> if you want parallel fetching (default 4).</li>
<li>Click <strong>Start Scan</strong>. Findings stream into the table as they're discovered.</li>
<li>Click any row to populate the Details / Request / Response tabs.</li>
</ol>
<div class="note info">
<strong>Re-running a scan:</strong> v1.7.6 auto-clears previous findings, dedup state, and the capture store when you click Start Scan again. Earlier versions appended to the prior run, which silently suppressed duplicates.
</div>
<h2>5.2 MITM Proxy</h2>
<ol>
<li><strong>Settings → Proxy → Start Proxy.</strong> Default port is <code>8888</code>.</li>
<li>Click <strong>Export CA Certificate…</strong> and save <code>SecretSifterCA.crt</code>.</li>
<li>Import the .crt into your browser's trusted root authority store:
<ul>
<li><strong>Chrome / Edge:</strong> Settings → Privacy & security → Security → Manage certificates → Authorities tab → Import.</li>
<li><strong>Firefox:</strong> Settings → Privacy & Security → View Certificates → Authorities → Import.</li>
</ul>
</li>
<li>Configure your browser's HTTP & HTTPS proxy to <code>127.0.0.1:8888</code> (no comma in the port).</li>
<li>Browse normally. Each intercepted request is logged in the <strong>Logs</strong> tab as <code>[Proxy] METHOD url</code>. Findings flow into the <strong>Scan</strong> tab.</li>
</ol>
<div class="note warn">
<strong>HSTS sites:</strong> some banks / cloud consoles refuse non-trusted CAs even after manual import. You'll see SSL errors that can't be bypassed; these hosts are out of scope for the proxy. Use the bulk scanner or HAR import instead.
</div>
<h2>5.3 HAR Import</h2>
<ol>
<li>In Chrome / Firefox, open DevTools → Network tab. Browse the target session.</li>
<li>Right-click in the request list → <em>Save all as HAR with content</em>.</li>
<li>In SecretSifter: <strong>Scan → Import HAR…</strong> → select the .har file.</li>
<li>Every request / response in the HAR is restored to the capture store and run through the scanner. The Details panel works the same as if the proxy had captured them.</li>
</ol>
<h2>5.4 Custom Rules</h2>
<ol>
<li><strong>Settings → Custom Rules.</strong></li>
<li>One rule per line, format: <code>RuleName | regex | severity</code> where severity ∈ HIGH / MEDIUM / LOW / INFORMATION.</li>
<li>Lines starting with <code>#</code> are comments.</li>
<li><strong>Enable custom rules</strong> — adds your rules on top of built-in detection.</li>
<li><strong>Use custom rules ONLY</strong> — runs only your regexes; bypasses every default noise filter (raw mode).</li>
</ol>
<pre><span class="c"># Example custom rules</span>
TelegramBotToken | \b[0-9]{5,16}:A[0-9A-Za-z_-]{34}\b | HIGH
HuggingFaceToken | \bhf_[A-Za-z0-9]{34}\b | HIGH
InternalToken | INT-[0-9]{8}-[A-Z]{4} | HIGH
ServiceAccount | sa-[a-z0-9]{16}@internal\.example\.com | MEDIUM</pre>
<h2>5.5 Triage</h2>
<ol>
<li>Click a row in the findings table.</li>
<li>The <strong>Details</strong> tab shows Rule ID / Name, Key, Line, Source URL, Target URL, Matched Value (with 📋 copy), and Context.</li>
<li>Adjust <strong>Severity</strong> or <strong>Confidence</strong> via the dropdowns — changes are reflected in the table immediately.</li>
<li>Mark a finding as NOISE by setting either Severity or Confidence to NOISE; it's then excluded from CSV / JSON / HTML / ZIP exports (but available via "Export Suppressed (NOISE) CSV").</li>
<li><strong>Mask Value</strong> dots out the Value column for screenshots; <strong>Mask URL</strong> covers both URL and Target columns.</li>
</ol>
<!-- ═════════════════════════════════ 6. DETECTION ═════════════════════════════════ -->
<h1 id="detection">6. Detection Engine Deep Dive</h1>
<h2>6.1 Pipeline</h2>
<p>For each fetched response body, the scanner runs (in tier-aware order):</p>
<ol>
<li>Form-encoded pre-pass (OAuth-style bodies)</li>
<li>HTML inline-script extraction (recursing as JS)</li>
<li>JSON_SCRIPT_TAG (<code>__NEXT_DATA__</code> etc.)</li>
<li>Headers-blob path (REQ-HEADERS)</li>
<li>Anchored vendor tokens (Phase 1)</li>
<li>URL credentials (Phase 2)</li>
<li>Custom rules</li>
<li>DB connection strings + context-gated rules (LIGHT, FULL)</li>
<li>GENERIC_KV — full text, no truncation (FULL)</li>
<li>SSR state blobs + high-entropy values + getter functions (FULL)</li>
<li>JWT severity adjustment (HIGH in JSON, MEDIUM in JS)</li>
<li>Two-pass deduplication (line-aware)</li>
</ol>
<h2>6.2 GENERIC_KV — The Workhorse</h2>
<p>The single most-fired rule. Matches <code>"key" : "value"</code> or <code>key=value</code> patterns where the key is semantically a credential name and the value passes entropy / shape checks. Runs on the entire text body — no truncation — because Angular / webpack bundles routinely exceed 5 MB and middle-of-bundle keys must not be sampled out.</p>
<p>Common findings:</p>
<ul>
<li><code>"subscription_Key": "<hex>"</code> → HIGH</li>
<li><code>"appKey": "<base64>"</code> → HIGH</li>
<li><code>"resource": "<uuid>"</code> → HIGH</li>
<li><code>"clientId": "<uuid>"</code> → INFORMATION</li>
<li><code>"tenantId": "<uuid>"</code> → INFORMATION</li>
</ul>
<h2>6.3 Why Findings Repeat at Different Lines</h2>
<p>v1.7.1 introduced line-aware deduplication. When the same key+value appears at lines 14, 15, 33, 35, 5321, 5335, … 169754 in a multi-MB Angular bundle, each is a real textual occurrence — not a duplicate. Burp reports them all, and so does SecretSifter. Pass 1 dedup keys on <code>(keyName, value, sourceUrl, line)</code>, not just <code>(keyName, value, sourceUrl)</code>.</p>
<h2>6.4 Why an Anchored Rule Can "Win" Over GENERIC_KV</h2>
<p>If GOOGLE_KEY_001 fires at line 42 with value <code>AIzaSy…</code> and GENERIC_KV also fires at line 42 with key <code>apiKey</code> and the same value, dedup Pass 2 keeps GOOGLE_KEY_001 and drops GENERIC_KV. The anchored rule carries the vendor classification ("Google API Key") which is more useful than a generic key label.</p>
<!-- ═════════════════════════════════ 7. SEVERITY ═════════════════════════════════ -->
<h1 id="severity">7. Severity & Confidence Model</h1>
<h2>7.1 Severity Levels</h2>
<table>
<tr><th>Level</th><th>When emitted</th></tr>
<tr><td><span class="badge b-r">CRITICAL</span></td><td>AWS Secret Key, GitHub PAT, Stripe live secret, CryptoJS-encrypted blob — credentials whose disclosure has immediate impact</td></tr>
<tr><td><span class="badge b-r">HIGH</span></td><td>Azure subscription / resource keys, Google API keys, Slack tokens, JWT in JSON response, OAuth client secrets, Twilio auth tokens, SendGrid keys</td></tr>
<tr><td><span class="badge b-o">MEDIUM</span></td><td>JWT in JS source, Twilio Account SID, GUID-as-credential, generic semantic-key matches without specific signal</td></tr>
<tr><td><span class="badge b-y">LOW</span></td><td>AppInsights instrumentation key, schema-field IDs, default catch-all</td></tr>
<tr><td><span class="badge b-b">INFORMATION</span></td><td>Client IDs, tenant IDs, app IDs, account IDs — public-by-design identifiers</td></tr>
<tr><td><span class="badge b-g">NOISE</span></td><td>User-set triage state — finding stays visible but is excluded from non-suppressed exports</td></tr>
</table>
<h2>7.2 Confidence Levels</h2>
<table>
<tr><th>Level</th><th>Meaning</th></tr>
<tr><td><span class="badge b-r">CERTAIN</span></td><td>Anchored prefix match (e.g., <code>AKIA...</code>, <code>AIza...</code>) or content-type-restricted JWT — false-positive rate < 1%</td></tr>
<tr><td><span class="badge b-o">FIRM</span></td><td>Semantic key + entropy gate passed — most GENERIC_KV findings</td></tr>
<tr><td><span class="badge b-y">TENTATIVE</span></td><td>Entropy-only signal — review the context before acting</td></tr>
<tr><td><span class="badge b-g">NOISE</span></td><td>Triaged-out</td></tr>
</table>
<!-- ═════════════════════════════════ 8. TRIAGE ═════════════════════════════════ -->
<h1 id="triage">8. Triage Guide & FP Determination</h1>
<h2>8.1 Validating a Finding</h2>
<ol>
<li>Read the <strong>Context</strong> field — is the value in a real-looking config object (e.g. <code>{ apiKey: "...", baseUrl: "https://api...." }</code>)?</li>
<li>Click the <strong>Source URL</strong> link — does the file actually contain the value at the reported line?</li>
<li>Open the <strong>Request</strong> / <strong>Response</strong> tabs to see the surrounding HTTP transaction.</li>
<li>If the value is a UUID, check whether it's a public client ID (Microsoft B2C apps, Auth0 client IDs, etc.) vs a secret.</li>
<li>Test the credential out-of-band where applicable (e.g., <code>curl -H "Ocp-Apim-Subscription-Key: ..." <api-base></code>).</li>
</ol>
<h2>8.2 Common False-Positive Shapes</h2>
<table>
<tr><th>Pattern</th><th>Why it's likely FP</th></tr>
<tr><td><code>"apiKey": "FirstName"</code></td><td>Schema field name in a CRUD form, not a credential. SecretSifter rejects all-alpha values; if you see one, please report it.</td></tr>
<tr><td><code>"clientID": "00000000-0000-0000-0000-000000000000"</code></td><td>Placeholder UUID; <code>isPlaceholder()</code> should reject it.</td></tr>
<tr><td><code>"key": ".bs.tab"</code> or <code>".data-api"</code></td><td>jQuery / Bootstrap event namespace, not a credential — filtered.</td></tr>
<tr><td><code>"apiKey": "${ENV_VAR}"</code></td><td>Template placeholder — filtered.</td></tr>
<tr><td><code>X-CSRF-Token</code> in headers</td><td>Anti-forgery token, public — filtered.</td></tr>
<tr><td>Public Microsoft B2C client IDs</td><td>Reported as INFORMATION because they're public, not secret. Mark as NOISE if irrelevant.</td></tr>
</table>
<h2>8.3 When to Mark NOISE</h2>
<p>Set Severity or Confidence to NOISE when:</p>
<ul>
<li>You've manually verified the value is a public identifier or test fixture.</li>
<li>The finding is a placeholder you can't reproduce in the wild.</li>
<li>Your scope explicitly excludes this kind of finding (e.g., a pentest scope that excludes informational disclosures).</li>
</ul>
<p>NOISE findings are still visible (greyed) so you can audit your triage later, and exportable separately via <em>Export Data → Export Suppressed (NOISE) CSV</em>.</p>
<!-- ═════════════════════════════════ 9. SETTINGS ═════════════════════════════════ -->
<h1 id="settings">9. Settings Reference</h1>
<h2>9.1 Scanner Tab</h2>
<table>
<tr><th>Setting</th><th>Default</th><th>Notes</th></tr>
<tr><td>Enable scanning</td><td>on</td><td>Master switch</td></tr>
<tr><td>Scan tier</td><td>FULL</td><td>FAST / LIGHT / FULL trade thoroughness for speed</td></tr>
<tr><td>Entropy threshold</td><td>3.5</td><td>Lower = more findings, higher = fewer</td></tr>
<tr><td>PII detection</td><td>on</td><td>SSN, credit cards</td></tr>
<tr><td>Scan request headers</td><td>on</td><td>Catches Authorization, Ocp-Apim-Subscription-Key, etc.</td></tr>
<tr><td>Browser path</td><td>(auto)</td><td>Override Chrome / Edge auto-detection</td></tr>
<tr><td>Playwright max pages</td><td>100</td><td>Per-target crawl cap</td></tr>
<tr><td>URL timeout</td><td>0 (no limit)</td><td>Per-URL fetch ceiling</td></tr>
<tr><td>Cross-origin APIs</td><td>off</td><td>Allow crawler to follow API calls outside the seed origin</td></tr>
<tr><td>Strict scope</td><td>off</td><td>Only scan exact-host matches (no subdomains)</td></tr>
<tr><td>Key blocklist</td><td>5 entries</td><td>Findings whose key contains a blocklist entry are dropped</td></tr>
<tr><td>Key allowlist</td><td>(empty)</td><td>Allowlist wins over blocklist</td></tr>
</table>
<h2>9.2 Custom Rules Tab</h2>
<table>
<tr><th>Setting</th><th>Default</th><th>Notes</th></tr>
<tr><td>Custom rules text</td><td>(template)</td><td>One <code>RuleName | regex | severity</code> per line</td></tr>
<tr><td>Enable custom rules</td><td>on</td><td>Run additively with built-in detection</td></tr>
<tr><td>Use custom rules ONLY</td><td>off</td><td>Skip built-ins entirely. Raw mode bypasses noise filters too — every regex match reported, FPs included</td></tr>
</table>
<h2>9.3 AI / MCP Tab</h2>
<table>
<tr><th>Setting</th><th>Default</th><th>Notes</th></tr>
<tr><td>Enable MCP server</td><td>off</td><td>Starts the local JSON-RPC + REST server</td></tr>
<tr><td>Port</td><td>random 8000–9000</td><td>Bound to localhost only</td></tr>
<tr><td>Token</td><td>random 32-hex</td><td>Bearer auth; regenerable</td></tr>
<tr><td>AI Provider API Key</td><td>(empty)</td><td>Optional outbound key for future AI features. Stored locally only.</td></tr>
</table>
<h2>9.4 Proxy Tab</h2>
<table>
<tr><th>Setting</th><th>Default</th><th>Notes</th></tr>
<tr><td>Port</td><td>8888</td><td>Bound to <code>0.0.0.0</code></td></tr>
<tr><td>Start / Stop</td><td>—</td><td>Toggle proxy listener</td></tr>
<tr><td>Export CA Certificate</td><td>—</td><td>Save the on-the-fly CA so browsers will trust per-host certs</td></tr>
</table>
<!-- ═════════════════════════════════ 10. REST API ═════════════════════════════════ -->
<h1 id="rest">10. REST API & MCP Quickstart</h1>
<p class="lead">Once MCP is enabled (Settings → AI / MCP → Apply), SecretSifter exposes a JSON-RPC + REST surface on <code>http://localhost:<port></code>. Bearer-authenticated.</p>
<h2>10.1 Endpoint Catalog</h2>
<table>
<tr><th>Path</th><th>Method</th><th>Description</th></tr>
<tr><td>/mcp</td><td>GET</td><td>Health probe</td></tr>
<tr><td>/mcp</td><td>POST</td><td>JSON-RPC 2.0 — initialize, tools/list, tools/call</td></tr>
<tr><td>/api/scan</td><td>POST</td><td>Start a scan: <code>{"urls": ["..."]}</code></td></tr>
<tr><td>/api/scan</td><td>GET</td><td>Status</td></tr>
<tr><td>/api/scan</td><td>DELETE</td><td>Stop running scan</td></tr>
<tr><td>/api/scan/status</td><td>GET</td><td>Detailed status object</td></tr>
<tr><td>/api/findings</td><td>GET</td><td>All findings (filters: <code>?severity=…</code>, <code>?target_url=…</code>)</td></tr>
<tr><td>/api/findings</td><td>DELETE</td><td>Clear findings</td></tr>
<tr><td>/api/findings/<row></td><td>PATCH</td><td>Update severity / confidence</td></tr>
<tr><td>/api/findings/<row></td><td>DELETE</td><td>Delete a single finding</td></tr>
<tr><td>/api/report</td><td>POST</td><td>Export <code>{"format":"csv"|"json"|"html","path":"..."}</code></td></tr>
<tr><td>/api/settings</td><td>GET / PATCH</td><td>Read / update settings</td></tr>
<tr><td>/api/targets</td><td>GET</td><td>Per-target scan status</td></tr>
<tr><td>/api/rules</td><td>GET / PUT / POST</td><td>Custom rules (PUT replaces, POST appends)</td></tr>
<tr><td>/api/logs</td><td>GET / DELETE</td><td>Read / clear logs</td></tr>
</table>
<h2>10.2 PowerShell Smoke Test</h2>
<pre>$port = 8765
$token = "<paste from Settings → AI / MCP>"
$h = @{ Authorization = "Bearer $token" }
<span class="c"># Health</span>
Invoke-RestMethod -Uri "http://localhost:$port/mcp" -Headers $h
<span class="c"># Get findings</span>
Invoke-RestMethod -Uri "http://localhost:$port/api/findings" -Headers $h |
Format-Table severity, ruleId, keyName, value -AutoSize
<span class="c"># Start a scan</span>
$body = @{ urls = @("https://example.com") } | ConvertTo-Json
Invoke-RestMethod -Uri "http://localhost:$port/api/scan" -Method POST -Headers $h `
-Body $body -ContentType "application/json"</pre>
<h2>10.3 Python Snippet</h2>
<pre><span class="kw">import</span> requests
PORT = 8765
TOKEN = "..."
h = {"Authorization": <span class="s">f"Bearer {TOKEN}"</span>}
<span class="c"># start scan</span>
requests.post(<span class="s">f"http://localhost:{PORT}/api/scan"</span>,
headers=h, json={<span class="s">"urls"</span>: [<span class="s">"https://example.com"</span>]})
<span class="c"># poll until idle</span>
<span class="kw">while</span> requests.get(<span class="s">f"http://localhost:{PORT}/api/scan/status"</span>, headers=h)
.json()[<span class="s">"running"</span>]:
time.sleep(2)
<span class="c"># fetch findings</span>
findings = requests.get(<span class="s">f"http://localhost:{PORT}/api/findings"</span>, headers=h).json()</pre>
<h2>10.4 Claude Code Integration</h2>
<p>From Settings → AI / MCP, click <strong>Copy CLI Command</strong> and run it in a terminal:</p>
<pre>claude mcp add --transport http secretsifter-desktop \
http://localhost:<port>/mcp \
--header "Authorization: Bearer <token>"</pre>
<p>Claude can then start scans, read findings, and export reports through the MCP protocol.</p>
<!-- ═════════════════════════════════ 11. EXPORTS ═════════════════════════════════ -->
<h1 id="exports">11. Reports & Exports</h1>
<h2>11.1 Export Reports — All-in-One ZIP</h2>
<p>Click <strong>Export Reports ▾ → All-in-One Report (HTML + CSV + JSON ZIP)</strong>. Produces:</p>
<table>
<tr><th>File</th><th>Content</th></tr>
<tr><td><code>secretsifter_report_<timestamp>.html</code></td><td>Single-page HTML report with sortable JS table, severity filter, free-text search</td></tr>
<tr><td><code>secretsifter_findings_<timestamp>.csv</code></td><td>CSV (column order matches HTML)</td></tr>
<tr><td><code>secretsifter_findings_<timestamp>.json</code></td><td>Pretty-printed JSON array</td></tr>
<tr><td><code>secretsifter_suppressed_<timestamp>.csv</code></td><td>NOISE-marked findings (only if any exist)</td></tr>
</table>
<h2>11.2 Export Reports — Per-Domain ZIP</h2>
<p>Click <strong>Export Reports ▾ → Per-Domain Reports (HTMLs + CSV + JSON ZIP)</strong>. Produces:</p>
<ul>
<li>One HTML report per domain found in the scan (e.g. <code>example.com_secretsifter_<ts>.html</code>).</li>
<li>Combined CSV + combined JSON across all domains.</li>
<li>Suppressed CSV (if any).</li>
</ul>
<h2>11.3 Export Data — Standalone CSV / JSON</h2>
<p>Use when you only need a single artifact:</p>
<ul>
<li><strong>Export CSV</strong> — non-NOISE findings as CSV</li>
<li><strong>Export JSON</strong> — non-NOISE findings as JSON</li>
<li><strong>Export Suppressed (NOISE) CSV</strong> — only triaged-out rows</li>
</ul>
<h2>11.4 CSV Column Order</h2>
<p>Severity, Confidence, Rule ID, Rule Name, Key, Value, URL, Target, Line, Context — matches the HTML report.</p>
<!-- ═════════════════════════════════ 12. TROUBLESHOOTING ═════════════════════════════════ -->
<h1 id="troubleshooting">12. Troubleshooting</h1>
<h2>12.1 Scanner missing findings Burp catches</h2>
<table>
<tr><th>Symptom</th><th>Likely cause</th><th>Fix</th></tr>
<tr><td>Subscription key reported once instead of 30+ times</td><td>Pre-v1.7.1 dedup collapsed across lines</td><td>Update to v1.7.1+; current version is line-aware</td></tr>
<tr><td>Findings missing on multi-MB Angular bundles</td><td>Pre-v1.7.0 truncated GENERIC_KV input at 1.5 MB</td><td>v1.7.0+ runs GENERIC_KV on full text</td></tr>
<tr><td>Vapid key not detected</td><td>Pre-v1.7.0 missing prefix</td><td>Update; <code>vapid</code> is in SECRET_KEY_PREFIXES</td></tr>
<tr><td>Bare-word semantic keys missed (<code>resource</code>)</td><td>Pre-v1.7.0 required ≥2 segments</td><td>Update; single-word allowlist now applies</td></tr>
</table>
<h2>12.2 Crawler blocked by Akamai / Cloudflare</h2>
<p>Symptom: corporate WiFi blocks the scan with "Access Denied" / Akamai error reference. Hotspot works.</p>
<ul>
<li>v1.7.2+ launches real Chrome via <code>setChannel("chrome")</code> with <code>--disable-blink-features=AutomationControlled</code>. Most Akamai bot checks pass.</li>
<li>If still blocked: try setting <em>Browser path</em> in Settings to your Chrome install explicitly.</li>
<li>Last resort: run the proxy mode and browse manually — once Akamai's <code>bm_sz</code> / <code>_abck</code> cookies are issued, traffic flows through.</li>
</ul>
<h2>12.3 Proxy "not intercepting traffic"</h2>
<table>
<tr><th>Cause</th><th>Fix</th></tr>
<tr><td>Browser proxy field has comma in port</td><td>v1.7.4 strips the comma. Use <code>127.0.0.1:8888</code> (no comma)</td></tr>
<tr><td>Cert not imported</td><td>Export CA, import into browser's trusted root authorities</td></tr>
<tr><td>Logs tab shows nothing on intercepted requests</td><td>Update to v1.7.4+ — every request now logs <code>[Proxy] METHOD url</code></td></tr>
<tr><td>Site uses HTTP/2 only</td><td>Proxy is HTTP/1.1; modern sites may not capture cleanly</td></tr>
</table>
<h2>12.4 Build fails with WiX exit code 297</h2>
<p>Out of disk during MSI link. <code>build/libs/</code> accumulates one stale ~175 MB JAR per build. Delete or archive every <code>secretsifter-*.jar</code> in <code>build/libs/</code> except the current version, then retry <code>gradle buildExeInstaller</code>.</p>
<h2>12.5 High idle CPU</h2>
<p>If SecretSifter shows > 10% CPU when not scanning, check Task Manager → Details. If <code>chrome.exe</code> is the culprit, a Playwright browser leaked from a prior scan — restart the app. If it's <code>SecretSifter.exe</code> / <code>javaw.exe</code>, please file a report with the version and OS build.</p>
<!-- ═════════════════════════════════ 13. REQUIREMENTS ═════════════════════════════════ -->
<h1 id="requirements">13. Requirements & Compatibility</h1>
<h2>13.1 Supported</h2>
<table>
<tr><th>Component</th><th>Supported</th></tr>
<tr><td>Windows 10 / 11 (x64)</td><td>✓</td></tr>
<tr><td>Java</td><td>Bundled (jpackage)</td></tr>
<tr><td>Browser</td><td>Chrome (preferred), bundled Chromium, system Edge</td></tr>
<tr><td>Proxy clients</td><td>Chrome, Edge, Firefox, native Windows app traffic</td></tr>
<tr><td>HAR formats</td><td>Chrome / Firefox / Edge DevTools standard HAR 1.2</td></tr>
<tr><td>MCP clients</td><td>Claude Desktop, Claude Code, Cursor, any custom MCP client</td></tr>
<tr><td>HTTP versions</td><td>HTTP/1.0, HTTP/1.1 — proxy</td></tr>
</table>
<h2>13.2 Unsupported / Limitations</h2>
<ul>
<li>HTTP/2 / HTTP/3 — proxy will fail to intercept; modern sites may degrade.</li>
<li>macOS / Linux — desktop edition is Windows-only. Use the Burp extension on other platforms.</li>
<li>Multi-user shared install — settings live in <code>HKCU</code>, so each user has their own state.</li>
</ul>
<h2>13.3 Feature Matrix vs Burp Extension Edition</h2>
<table>
<tr><th>Feature</th><th>Burp Edition</th><th>Desktop Edition</th></tr>
<tr><td>Bulk URL scan</td><td>✓</td><td>✓</td></tr>
<tr><td>Passive scanning of Burp's site map</td><td>✓</td><td>—</td></tr>
<tr><td>Embedded MITM proxy</td><td>(Burp's)</td><td>✓ (own)</td></tr>
<tr><td>Playwright crawler</td><td>✓</td><td>✓</td></tr>
<tr><td>HAR import</td><td>✓</td><td>✓</td></tr>
<tr><td>MCP / REST API</td><td>✓</td><td>✓</td></tr>
<tr><td>Custom rules + raw mode</td><td>(no raw mode)</td><td>✓</td></tr>
<tr><td>Capture store + Details panel</td><td>(uses Burp's)</td><td>✓ (own)</td></tr>
<tr><td>Cost</td><td>Free, but Burp licence required</td><td>Free, no Burp needed</td></tr>
</table>
<!-- ═════════════════════════════════ 14. BUILDING ═════════════════════════════════ -->
<h1 id="building">14. Building from Source</h1>
<h2>14.1 Prerequisites</h2>
<ul>
<li>JDK 17+ with <code>jpackage</code> (bundled in JDK 14+).</li>
<li>WiX Toolset 3.11+ on PATH (for the EXE installer).</li>
<li>Gradle (the wrapper script <code>gradlew.bat</code> is bundled).</li>
</ul>
<h2>14.2 Build Steps</h2>
<pre><span class="c"># Obfuscated fat JAR (~1m)</span>
gradlew reinsertObfuscatedClasses
<span class="c"># Portable app-image (~2m)</span>
gradlew buildAppImage
<span class="c"># Full Windows EXE installer (~3m)</span>
gradlew buildExeInstaller</pre>
<div class="note warn">
<strong>Stale-JAR trap:</strong> delete every <code>secretsifter-<version>.jar</code> in <code>build/libs/</code> except the current version before each <code>buildExeInstaller</code> run, otherwise <code>jpackage</code> bundles them all into the installer image and WiX <code>light.exe</code> may fail with exit code 297 on systems with low disk space.
</div>
<h2>14.3 Output</h2>
<table>
<tr><th>Path</th><th>Artifact</th></tr>
<tr><td><code>build/libs/secretsifter-<ver>.jar</code></td><td>Obfuscated fat JAR</td></tr>
<tr><td><code>build/app-image-protected/SecretSifter/</code></td><td>Portable folder + JRE</td></tr>
<tr><td><code>build/exe-installer/SecretSifter-<ver>.exe</code></td><td>Windows installer</td></tr>
</table>
<!-- ═════════════════════════════════ 15. CREDITS ═════════════════════════════════ -->
<h1 id="credits">15. Credits & License</h1>
<p class="lead">Attribution, open-source notices, and licensing terms.</p>
<h2>15.1 License</h2>
<p>SecretSifter is released under the <strong>MIT License</strong>.</p>
<pre>MIT License
Copyright (c) 2024–2026 Hemanth Gorijala
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.</pre>
<h2>15.2 Third-Party Notices</h2>
<p>Vendor token format specifications are publicly documented by their respective service providers (AWS, Azure, Google, GitHub, GitLab, Stripe, OpenAI, Slack, Twilio, SendGrid, Mailgun, Heroku, npm, PyPI, and others). The regex patterns implementing those formats are the author's independent work.</p>
<p>The desktop edition bundles the following open-source components:</p>
<table>
<tr><th>Component</th><th>Author / Project</th><th>License</th><th>Use</th></tr>
<tr><td>Playwright for Java</td><td>Microsoft</td><td>Apache 2.0</td><td>Browser-driven crawler</td></tr>
<tr><td>Bouncy Castle</td><td>The Legion of the Bouncy Castle</td><td>MIT-style</td><td>On-the-fly per-host TLS certificate generation for the MITM proxy</td></tr>
<tr><td>org.json</td><td>JSON.org</td><td>JSON License</td><td>JSON serialization for REST / MCP</td></tr>
<tr><td>ProGuard</td><td>Guardsquare</td><td>Apache 2.0 (build-time)</td><td>Identifier obfuscation</td></tr>
<tr><td>Bundled Chromium</td><td>Chromium Authors</td><td>BSD</td><td>Fallback browser when system Chrome is absent</td></tr>
<tr><td>OpenJDK 21</td><td>Oracle / OpenJDK</td><td>GPLv2 + Classpath Exception</td><td>Bundled JRE inside the jpackage installer</td></tr>
<tr><td>WiX Toolset</td><td>WiX Toolset Project</td><td>MS-RL (build-time only)</td><td>Windows installer link step</td></tr>
</table>
<h2>15.3 Author</h2>
<table>
<tr><th>Field</th><th>Detail</th></tr>
<tr><td>Author</td><td>Hemanth Gorijala</td></tr>
<tr><td>ORCID</td><td>0009-0006-9810-4001</td></tr>
<tr><td>Repository</td><td><code>https://github.com/secretsifter/secretsifter-windows</code></td></tr>
<tr><td>License</td><td>MIT</td></tr>
<tr><td>Distribution</td><td>Windows EXE installer (jpackage / WiX)</td></tr>
<tr><td>Companion edition</td><td>Secret Sifter (PortSwigger BApp Store) — Burp Suite extension</td></tr>
</table>
<h2>15.4 Legal Notice</h2>
<p>SecretSifter is a security research and penetration testing tool. You are solely responsible for ensuring that your use of this software complies with all applicable laws and regulations in your jurisdiction. Only use SecretSifter against systems you own or have explicit written authorisation to test. Unauthorised scanning of third-party systems may violate computer fraud laws.</p>
<div class="note warn">
<strong>Authorized Use Only.</strong> SecretSifter is designed exclusively for use on systems and applications you own or have explicit written permission to test. Unauthorized scanning, probing, or credential harvesting against systems you do not own or have not been authorized to test is illegal under the Computer Fraud and Abuse Act (CFAA), the UK Computer Misuse Act, the EU Directive on Attacks Against Information Systems, and equivalent legislation in other jurisdictions.
</div>
<h3>Disclaimer of Warranty</h3>
<p>SecretSifter is provided <strong>"as is"</strong>, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non-infringement. The author makes no representations or warranties regarding the completeness, accuracy, or reliability of detection results. False positives and false negatives are inherent to pattern-based secret detection and should be expected.</p>
<h3>Limitation of Liability</h3>
<p>In no event shall the author or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including but not limited to procurement of substitute goods or services; loss of use, data, or profits; or business interruption) arising from the use of or inability to use this software, even if advised of the possibility of such damages.</p>
<h3>Responsible Disclosure</h3>
<p>If SecretSifter identifies credentials or secrets belonging to third-party services in the course of authorized testing, the tester is responsible for following the applicable responsible disclosure or coordinated vulnerability disclosure (CVD) process. The author accepts no liability for the handling of disclosed findings.</p>
<h3>Export and Compliance</h3>
<p>This software may be subject to export control laws and regulations. Users are solely responsible for ensuring their use of SecretSifter complies with all applicable local, national, and international laws, including export control regulations.</p>
<h3>Data Handling & Local Storage</h3>
<p>SecretSifter stores all configuration (settings, custom rules, MCP token, AI provider key) locally in the Windows registry under <code>HKCU\Software\JavaSoft\Prefs\com\secretsifter</code> and never transmits it to any external service. Captured HTTP request / response bodies live only in process memory inside the bounded <code>CaptureStore</code> (max 500 entries, 2 MB per body) and are discarded on exit. The MCP / REST server binds to <code>localhost</code> only and is not exposed to the network.</p>
<div class="note ok" style="margin-top:32px;">
<strong>End of User Documentation v1.7.6.</strong> See the companion <em>SecretSifter Desktop Engineering Reference</em> for pipeline internals, rule tables, dedup architecture, and the full version history.
</div>
<div style="text-align:center;margin-top:36px;padding-top:18px;border-top:1px solid var(--border);
color:#999;font-size:11.5px;">
SecretSifter v1.7.6 • Windows Desktop Edition • Author: Hemanth Gorijala • MIT License
</div>
</div>
</body>
</html>