supasec 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/Feature-List.md +233 -0
  2. package/README.md +53 -12
  3. package/dist/cli.js +2 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/index.d.ts +1 -0
  6. package/dist/commands/index.d.ts.map +1 -1
  7. package/dist/commands/index.js +1 -0
  8. package/dist/commands/index.js.map +1 -1
  9. package/dist/commands/scan.d.ts.map +1 -1
  10. package/dist/commands/scan.js +74 -18
  11. package/dist/commands/scan.js.map +1 -1
  12. package/dist/commands/snapshot.d.ts +32 -0
  13. package/dist/commands/snapshot.d.ts.map +1 -0
  14. package/dist/commands/snapshot.js +282 -0
  15. package/dist/commands/snapshot.js.map +1 -0
  16. package/dist/reporters/html.d.ts +3 -2
  17. package/dist/reporters/html.d.ts.map +1 -1
  18. package/dist/reporters/html.js +844 -538
  19. package/dist/reporters/html.js.map +1 -1
  20. package/dist/reporters/terminal.d.ts +38 -2
  21. package/dist/reporters/terminal.d.ts.map +1 -1
  22. package/dist/reporters/terminal.js +292 -131
  23. package/dist/reporters/terminal.js.map +1 -1
  24. package/dist/scanners/auth/analyzer.d.ts +40 -0
  25. package/dist/scanners/auth/analyzer.d.ts.map +1 -0
  26. package/dist/scanners/auth/analyzer.js +673 -0
  27. package/dist/scanners/auth/analyzer.js.map +1 -0
  28. package/dist/scanners/auth/index.d.ts +6 -0
  29. package/dist/scanners/auth/index.d.ts.map +1 -0
  30. package/dist/scanners/auth/index.js +22 -0
  31. package/dist/scanners/auth/index.js.map +1 -0
  32. package/dist/scanners/edge/analyzer.d.ts +35 -0
  33. package/dist/scanners/edge/analyzer.d.ts.map +1 -0
  34. package/dist/scanners/edge/analyzer.js +614 -0
  35. package/dist/scanners/edge/analyzer.js.map +1 -0
  36. package/dist/scanners/edge/index.d.ts +6 -0
  37. package/dist/scanners/edge/index.d.ts.map +1 -0
  38. package/dist/scanners/edge/index.js +22 -0
  39. package/dist/scanners/edge/index.js.map +1 -0
  40. package/dist/scanners/functions/analyzer.d.ts +41 -0
  41. package/dist/scanners/functions/analyzer.d.ts.map +1 -0
  42. package/dist/scanners/functions/analyzer.js +378 -0
  43. package/dist/scanners/functions/analyzer.js.map +1 -0
  44. package/dist/scanners/functions/index.d.ts +6 -0
  45. package/dist/scanners/functions/index.d.ts.map +1 -0
  46. package/dist/scanners/functions/index.js +22 -0
  47. package/dist/scanners/functions/index.js.map +1 -0
  48. package/dist/scanners/git/index.d.ts +6 -0
  49. package/dist/scanners/git/index.d.ts.map +1 -0
  50. package/dist/scanners/git/index.js +22 -0
  51. package/dist/scanners/git/index.js.map +1 -0
  52. package/dist/scanners/git/scanner.d.ts +22 -0
  53. package/dist/scanners/git/scanner.d.ts.map +1 -0
  54. package/dist/scanners/git/scanner.js +531 -0
  55. package/dist/scanners/git/scanner.js.map +1 -0
  56. package/dist/scanners/https/analyzer.d.ts +42 -0
  57. package/dist/scanners/https/analyzer.d.ts.map +1 -0
  58. package/dist/scanners/https/analyzer.js +470 -0
  59. package/dist/scanners/https/analyzer.js.map +1 -0
  60. package/dist/scanners/https/index.d.ts +8 -0
  61. package/dist/scanners/https/index.d.ts.map +1 -0
  62. package/dist/scanners/https/index.js +17 -0
  63. package/dist/scanners/https/index.js.map +1 -0
  64. package/dist/scanners/index.d.ts +6 -0
  65. package/dist/scanners/index.d.ts.map +1 -1
  66. package/dist/scanners/index.js +6 -0
  67. package/dist/scanners/index.js.map +1 -1
  68. package/dist/scanners/rls/fuzzer.d.ts +40 -0
  69. package/dist/scanners/rls/fuzzer.d.ts.map +1 -0
  70. package/dist/scanners/rls/fuzzer.js +360 -0
  71. package/dist/scanners/rls/fuzzer.js.map +1 -0
  72. package/dist/scanners/rls/index.d.ts +1 -0
  73. package/dist/scanners/rls/index.d.ts.map +1 -1
  74. package/dist/scanners/rls/index.js +1 -0
  75. package/dist/scanners/rls/index.js.map +1 -1
  76. package/dist/scanners/secrets/detector.d.ts.map +1 -1
  77. package/dist/scanners/secrets/detector.js +44 -12
  78. package/dist/scanners/secrets/detector.js.map +1 -1
  79. package/dist/scanners/secrets/index.d.ts +1 -0
  80. package/dist/scanners/secrets/index.d.ts.map +1 -1
  81. package/dist/scanners/secrets/index.js +4 -0
  82. package/dist/scanners/secrets/index.js.map +1 -1
  83. package/dist/scanners/secrets/patterns.d.ts +25 -0
  84. package/dist/scanners/secrets/patterns.d.ts.map +1 -1
  85. package/dist/scanners/secrets/patterns.js +138 -27
  86. package/dist/scanners/secrets/patterns.js.map +1 -1
  87. package/dist/scanners/storage/analyzer.d.ts +49 -0
  88. package/dist/scanners/storage/analyzer.d.ts.map +1 -0
  89. package/dist/scanners/storage/analyzer.js +438 -0
  90. package/dist/scanners/storage/analyzer.js.map +1 -0
  91. package/dist/scanners/storage/index.d.ts +6 -0
  92. package/dist/scanners/storage/index.d.ts.map +1 -0
  93. package/dist/scanners/storage/index.js +22 -0
  94. package/dist/scanners/storage/index.js.map +1 -0
  95. package/package.json +1 -1
  96. package/reports/supasec-audityour-app-2026-01-28-19-42-22.html +757 -0
  97. package/reports/supasec-audityour-app-2026-01-28-19-49-18.html +1122 -0
@@ -0,0 +1,1122 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>SupaSec Security Audit Report</title>
7
+ <style>
8
+ :root {
9
+ --color-bg: #f8fafc;
10
+ --color-card: #ffffff;
11
+ --color-text: #1e293b;
12
+ --color-text-secondary: #64748b;
13
+ --color-border: #e2e8f0;
14
+ --color-primary: #3b82f6;
15
+ --color-primary-light: #eff6ff;
16
+ --color-success: #22c55e;
17
+ --color-warning: #f59e0b;
18
+ --color-danger: #ef4444;
19
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
20
+ --shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
21
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
22
+ --radius-sm: 6px;
23
+ --radius: 12px;
24
+ --radius-lg: 16px;
25
+ }
26
+
27
+ * {
28
+ margin: 0;
29
+ padding: 0;
30
+ box-sizing: border-box;
31
+ }
32
+
33
+ body {
34
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
35
+ background: var(--color-bg);
36
+ min-height: 100vh;
37
+ color: var(--color-text);
38
+ line-height: 1.6;
39
+ }
40
+
41
+ .container {
42
+ max-width: 1200px;
43
+ margin: 0 auto;
44
+ padding: 24px;
45
+ }
46
+
47
+ /* Header */
48
+ .header {
49
+ background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
50
+ padding: 32px;
51
+ border-radius: var(--radius-lg);
52
+ margin-bottom: 24px;
53
+ box-shadow: var(--shadow-lg);
54
+ color: white;
55
+ }
56
+
57
+ .header-top {
58
+ display: flex;
59
+ align-items: center;
60
+ justify-content: space-between;
61
+ margin-bottom: 24px;
62
+ }
63
+
64
+ .brand {
65
+ display: flex;
66
+ align-items: center;
67
+ gap: 12px;
68
+ }
69
+
70
+ .logo {
71
+ width: 48px;
72
+ height: 48px;
73
+ background: rgba(255,255,255,0.2);
74
+ border-radius: var(--radius);
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+ font-size: 24px;
79
+ font-weight: 700;
80
+ backdrop-filter: blur(10px);
81
+ }
82
+
83
+ .brand-text h1 {
84
+ font-size: 24px;
85
+ font-weight: 700;
86
+ margin: 0;
87
+ }
88
+
89
+ .brand-text p {
90
+ font-size: 13px;
91
+ opacity: 0.9;
92
+ margin: 0;
93
+ }
94
+
95
+ .report-meta {
96
+ text-align: right;
97
+ }
98
+
99
+ .report-id {
100
+ font-size: 12px;
101
+ opacity: 0.8;
102
+ font-family: monospace;
103
+ }
104
+
105
+ .report-date {
106
+ font-size: 13px;
107
+ opacity: 0.9;
108
+ }
109
+
110
+ /* Grade Section */
111
+ .grade-section {
112
+ display: flex;
113
+ align-items: center;
114
+ gap: 32px;
115
+ padding: 24px;
116
+ background: rgba(255,255,255,0.1);
117
+ border-radius: var(--radius);
118
+ backdrop-filter: blur(10px);
119
+ }
120
+
121
+ .grade-circle {
122
+ width: 120px;
123
+ height: 120px;
124
+ border-radius: 50%;
125
+ display: flex;
126
+ flex-direction: column;
127
+ align-items: center;
128
+ justify-content: center;
129
+ background: #eab308;
130
+ box-shadow: 0 8px 32px rgba(0,0,0,0.2);
131
+ position: relative;
132
+ }
133
+
134
+ .grade-circle::before {
135
+ content: '';
136
+ position: absolute;
137
+ inset: 4px;
138
+ border-radius: 50%;
139
+ border: 3px solid rgba(255,255,255,0.3);
140
+ }
141
+
142
+ .grade-letter {
143
+ font-size: 56px;
144
+ font-weight: 800;
145
+ line-height: 1;
146
+ }
147
+
148
+ .grade-score {
149
+ font-size: 14px;
150
+ font-weight: 600;
151
+ opacity: 0.9;
152
+ }
153
+
154
+ .grade-info {
155
+ flex: 1;
156
+ }
157
+
158
+ .grade-info h2 {
159
+ font-size: 20px;
160
+ font-weight: 600;
161
+ margin-bottom: 8px;
162
+ }
163
+
164
+ .grade-info p {
165
+ font-size: 14px;
166
+ opacity: 0.9;
167
+ margin-bottom: 16px;
168
+ }
169
+
170
+ .security-meter {
171
+ height: 8px;
172
+ background: rgba(255,255,255,0.2);
173
+ border-radius: 4px;
174
+ overflow: hidden;
175
+ }
176
+
177
+ .security-meter-fill {
178
+ height: 100%;
179
+ background: white;
180
+ border-radius: 4px;
181
+ transition: width 1s ease;
182
+ width: 75%;
183
+ }
184
+
185
+ .security-meter-labels {
186
+ display: flex;
187
+ justify-content: space-between;
188
+ margin-top: 4px;
189
+ font-size: 11px;
190
+ opacity: 0.8;
191
+ }
192
+
193
+ /* Target Info Card */
194
+ .target-card {
195
+ background: var(--color-card);
196
+ border: 1px solid var(--color-border);
197
+ border-radius: var(--radius);
198
+ padding: 20px;
199
+ margin-bottom: 24px;
200
+ box-shadow: var(--shadow-sm);
201
+ }
202
+
203
+ .target-card h3 {
204
+ font-size: 12px;
205
+ font-weight: 600;
206
+ text-transform: uppercase;
207
+ letter-spacing: 0.5px;
208
+ color: var(--color-text-secondary);
209
+ margin-bottom: 8px;
210
+ }
211
+
212
+ .target-url {
213
+ font-size: 16px;
214
+ font-weight: 500;
215
+ color: var(--color-primary);
216
+ word-break: break-all;
217
+ }
218
+
219
+ .target-meta {
220
+ display: flex;
221
+ gap: 24px;
222
+ margin-top: 16px;
223
+ padding-top: 16px;
224
+ border-top: 1px solid var(--color-border);
225
+ }
226
+
227
+ .target-meta-item {
228
+ display: flex;
229
+ flex-direction: column;
230
+ gap: 4px;
231
+ }
232
+
233
+ .target-meta-item span:first-child {
234
+ font-size: 11px;
235
+ color: var(--color-text-secondary);
236
+ text-transform: uppercase;
237
+ letter-spacing: 0.5px;
238
+ }
239
+
240
+ .target-meta-item span:last-child {
241
+ font-size: 13px;
242
+ font-weight: 500;
243
+ }
244
+
245
+ /* Stats Grid */
246
+ .stats-grid {
247
+ display: grid;
248
+ grid-template-columns: repeat(4, 1fr);
249
+ gap: 16px;
250
+ margin-bottom: 24px;
251
+ }
252
+
253
+ .stat-card {
254
+ background: var(--color-card);
255
+ border: 1px solid var(--color-border);
256
+ border-radius: var(--radius);
257
+ padding: 20px;
258
+ text-align: center;
259
+ box-shadow: var(--shadow-sm);
260
+ transition: transform 0.2s, box-shadow 0.2s;
261
+ }
262
+
263
+ .stat-card:hover {
264
+ transform: translateY(-2px);
265
+ box-shadow: var(--shadow);
266
+ }
267
+
268
+ .stat-icon {
269
+ width: 40px;
270
+ height: 40px;
271
+ border-radius: var(--radius-sm);
272
+ display: flex;
273
+ align-items: center;
274
+ justify-content: center;
275
+ margin: 0 auto 12px;
276
+ font-size: 20px;
277
+ }
278
+
279
+ .stat-icon.critical { background: #fef2f2; }
280
+ .stat-icon.high { background: #fffbeb; }
281
+ .stat-icon.medium { background: #fefce8; }
282
+ .stat-icon.low { background: #eff6ff; }
283
+
284
+ .stat-value {
285
+ font-size: 36px;
286
+ font-weight: 700;
287
+ line-height: 1;
288
+ margin-bottom: 4px;
289
+ }
290
+
291
+ .stat-value.critical { color: #dc2626; }
292
+ .stat-value.high { color: #d97706; }
293
+ .stat-value.medium { color: #a16207; }
294
+ .stat-value.low { color: #2563eb; }
295
+
296
+ .stat-label {
297
+ font-size: 12px;
298
+ font-weight: 600;
299
+ text-transform: uppercase;
300
+ letter-spacing: 0.5px;
301
+ color: var(--color-text-secondary);
302
+ }
303
+
304
+ /* Category Scores */
305
+ .category-section {
306
+ background: var(--color-card);
307
+ border: 1px solid var(--color-border);
308
+ border-radius: var(--radius);
309
+ padding: 24px;
310
+ margin-bottom: 24px;
311
+ box-shadow: var(--shadow-sm);
312
+ }
313
+
314
+ .category-section h2 {
315
+ font-size: 16px;
316
+ font-weight: 600;
317
+ margin-bottom: 20px;
318
+ display: flex;
319
+ align-items: center;
320
+ gap: 8px;
321
+ }
322
+
323
+ .category-grid {
324
+ display: grid;
325
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
326
+ gap: 16px;
327
+ }
328
+
329
+ .category-item {
330
+ display: flex;
331
+ align-items: center;
332
+ gap: 12px;
333
+ padding: 16px;
334
+ background: #f8fafc;
335
+ border-radius: var(--radius-sm);
336
+ }
337
+
338
+ .category-grade {
339
+ width: 40px;
340
+ height: 40px;
341
+ border-radius: 50%;
342
+ display: flex;
343
+ align-items: center;
344
+ justify-content: center;
345
+ font-weight: 700;
346
+ font-size: 14px;
347
+ flex-shrink: 0;
348
+ }
349
+
350
+ .category-info {
351
+ flex: 1;
352
+ }
353
+
354
+ .category-name {
355
+ font-size: 14px;
356
+ font-weight: 600;
357
+ margin-bottom: 4px;
358
+ text-transform: capitalize;
359
+ }
360
+
361
+ .category-bar {
362
+ height: 6px;
363
+ background: #e2e8f0;
364
+ border-radius: 3px;
365
+ overflow: hidden;
366
+ }
367
+
368
+ .category-bar-fill {
369
+ height: 100%;
370
+ border-radius: 3px;
371
+ transition: width 1s ease;
372
+ }
373
+
374
+ .category-score {
375
+ font-size: 12px;
376
+ font-weight: 600;
377
+ color: var(--color-text-secondary);
378
+ margin-left: 8px;
379
+ }
380
+
381
+ /* Findings Section */
382
+ .findings-section {
383
+ margin-bottom: 24px;
384
+ }
385
+
386
+ .section-header {
387
+ display: flex;
388
+ align-items: center;
389
+ justify-content: space-between;
390
+ margin-bottom: 20px;
391
+ }
392
+
393
+ .section-header h2 {
394
+ font-size: 20px;
395
+ font-weight: 600;
396
+ }
397
+
398
+ .section-header p {
399
+ font-size: 14px;
400
+ color: var(--color-text-secondary);
401
+ }
402
+
403
+ .finding-card {
404
+ background: var(--color-card);
405
+ border: 1px solid var(--color-border);
406
+ border-radius: var(--radius);
407
+ margin-bottom: 16px;
408
+ overflow: hidden;
409
+ box-shadow: var(--shadow-sm);
410
+ }
411
+
412
+ .finding-header {
413
+ padding: 20px;
414
+ cursor: pointer;
415
+ display: flex;
416
+ align-items: flex-start;
417
+ gap: 16px;
418
+ transition: background 0.2s;
419
+ }
420
+
421
+ .finding-header:hover {
422
+ background: #f8fafc;
423
+ }
424
+
425
+ .finding-severity {
426
+ width: 48px;
427
+ height: 48px;
428
+ border-radius: var(--radius-sm);
429
+ display: flex;
430
+ align-items: center;
431
+ justify-content: center;
432
+ font-size: 24px;
433
+ flex-shrink: 0;
434
+ }
435
+
436
+ .finding-severity.critical { background: #fef2f2; }
437
+ .finding-severity.high { background: #fffbeb; }
438
+ .finding-severity.medium { background: #fefce8; }
439
+ .finding-severity.low { background: #eff6ff; }
440
+
441
+ .finding-title-section {
442
+ flex: 1;
443
+ }
444
+
445
+ .finding-title {
446
+ font-size: 16px;
447
+ font-weight: 600;
448
+ margin-bottom: 4px;
449
+ display: flex;
450
+ align-items: center;
451
+ gap: 8px;
452
+ }
453
+
454
+ .finding-id {
455
+ font-size: 12px;
456
+ color: var(--color-text-secondary);
457
+ font-family: monospace;
458
+ }
459
+
460
+ .finding-preview {
461
+ font-size: 14px;
462
+ color: var(--color-text-secondary);
463
+ line-height: 1.5;
464
+ }
465
+
466
+ .finding-meta {
467
+ display: flex;
468
+ gap: 12px;
469
+ margin-top: 8px;
470
+ }
471
+
472
+ .finding-badge {
473
+ display: inline-flex;
474
+ align-items: center;
475
+ gap: 4px;
476
+ padding: 4px 10px;
477
+ border-radius: 20px;
478
+ font-size: 11px;
479
+ font-weight: 600;
480
+ text-transform: uppercase;
481
+ letter-spacing: 0.5px;
482
+ }
483
+
484
+ .finding-badge.critical { background: #fef2f2; color: #dc2626; }
485
+ .finding-badge.high { background: #fffbeb; color: #d97706; }
486
+ .finding-badge.medium { background: #fefce8; color: #a16207; }
487
+ .finding-badge.low { background: #eff6ff; color: #2563eb; }
488
+
489
+ .finding-category {
490
+ background: #e2e8f0;
491
+ color: #475569;
492
+ }
493
+
494
+ .finding-toggle {
495
+ width: 32px;
496
+ height: 32px;
497
+ border-radius: 50%;
498
+ display: flex;
499
+ align-items: center;
500
+ justify-content: center;
501
+ background: #e2e8f0;
502
+ color: #64748b;
503
+ transition: transform 0.2s;
504
+ }
505
+
506
+ .finding-content {
507
+ display: none;
508
+ padding: 0 20px 20px 84px;
509
+ border-top: 1px solid var(--color-border);
510
+ }
511
+
512
+ .finding-content.active {
513
+ display: block;
514
+ }
515
+
516
+ .finding-content-section {
517
+ padding: 20px 0;
518
+ border-bottom: 1px solid var(--color-border);
519
+ }
520
+
521
+ .finding-content-section:last-child {
522
+ border-bottom: none;
523
+ }
524
+
525
+ .finding-content-section h4 {
526
+ font-size: 12px;
527
+ font-weight: 600;
528
+ text-transform: uppercase;
529
+ letter-spacing: 0.5px;
530
+ color: var(--color-text-secondary);
531
+ margin-bottom: 12px;
532
+ }
533
+
534
+ .finding-content-section p {
535
+ font-size: 14px;
536
+ line-height: 1.7;
537
+ color: var(--color-text);
538
+ }
539
+
540
+ .finding-content-section ul {
541
+ list-style: none;
542
+ padding: 0;
543
+ }
544
+
545
+ .finding-content-section li {
546
+ font-size: 14px;
547
+ padding: 6px 0;
548
+ padding-left: 20px;
549
+ position: relative;
550
+ }
551
+
552
+ .finding-content-section li::before {
553
+ content: "→";
554
+ position: absolute;
555
+ left: 0;
556
+ color: var(--color-primary);
557
+ }
558
+
559
+ /* Code Blocks */
560
+ .code-block {
561
+ background: #1e293b;
562
+ border-radius: var(--radius-sm);
563
+ padding: 16px;
564
+ margin-top: 12px;
565
+ overflow-x: auto;
566
+ }
567
+
568
+ .code-block pre {
569
+ margin: 0;
570
+ font-family: 'Monaco', 'Consolas', 'Courier New', monospace;
571
+ font-size: 13px;
572
+ line-height: 1.6;
573
+ color: #e2e8f0;
574
+ }
575
+
576
+ .code-block code {
577
+ font-family: inherit;
578
+ }
579
+
580
+ /* Technical Details */
581
+ .tech-details {
582
+ background: #f8fafc;
583
+ border: 1px solid var(--color-border);
584
+ border-radius: var(--radius-sm);
585
+ padding: 16px;
586
+ margin-top: 16px;
587
+ }
588
+
589
+ .tech-details h5 {
590
+ font-size: 11px;
591
+ font-weight: 600;
592
+ text-transform: uppercase;
593
+ letter-spacing: 0.5px;
594
+ color: var(--color-text-secondary);
595
+ margin-bottom: 12px;
596
+ }
597
+
598
+ .tech-row {
599
+ display: flex;
600
+ margin-bottom: 12px;
601
+ }
602
+
603
+ .tech-row:last-child {
604
+ margin-bottom: 0;
605
+ }
606
+
607
+ .tech-label {
608
+ width: 120px;
609
+ font-size: 12px;
610
+ color: var(--color-text-secondary);
611
+ flex-shrink: 0;
612
+ }
613
+
614
+ .tech-value {
615
+ flex: 1;
616
+ font-size: 13px;
617
+ font-family: 'Monaco', 'Consolas', monospace;
618
+ color: var(--color-text);
619
+ word-break: break-all;
620
+ }
621
+
622
+ /* Passed Checks */
623
+ .passed-section {
624
+ background: var(--color-card);
625
+ border: 1px solid var(--color-border);
626
+ border-radius: var(--radius);
627
+ padding: 24px;
628
+ margin-bottom: 24px;
629
+ box-shadow: var(--shadow-sm);
630
+ }
631
+
632
+ .passed-section h2 {
633
+ font-size: 16px;
634
+ font-weight: 600;
635
+ margin-bottom: 16px;
636
+ display: flex;
637
+ align-items: center;
638
+ gap: 8px;
639
+ color: var(--color-success);
640
+ }
641
+
642
+ .passed-grid {
643
+ display: grid;
644
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
645
+ gap: 12px;
646
+ }
647
+
648
+ .passed-item {
649
+ display: flex;
650
+ align-items: flex-start;
651
+ gap: 12px;
652
+ padding: 12px;
653
+ background: #f0fdf4;
654
+ border: 1px solid #bbf7d0;
655
+ border-radius: var(--radius-sm);
656
+ }
657
+
658
+ .passed-icon {
659
+ width: 20px;
660
+ height: 20px;
661
+ border-radius: 50%;
662
+ background: #22c55e;
663
+ display: flex;
664
+ align-items: center;
665
+ justify-content: center;
666
+ color: white;
667
+ font-size: 12px;
668
+ flex-shrink: 0;
669
+ }
670
+
671
+ .passed-content h4 {
672
+ font-size: 13px;
673
+ font-weight: 600;
674
+ margin-bottom: 2px;
675
+ }
676
+
677
+ .passed-content p {
678
+ font-size: 12px;
679
+ color: var(--color-text-secondary);
680
+ }
681
+
682
+ /* Quick Actions */
683
+ .actions-section {
684
+ background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
685
+ border-radius: var(--radius);
686
+ padding: 24px;
687
+ margin-bottom: 24px;
688
+ color: white;
689
+ }
690
+
691
+ .actions-section h2 {
692
+ font-size: 16px;
693
+ font-weight: 600;
694
+ margin-bottom: 16px;
695
+ }
696
+
697
+ .actions-grid {
698
+ display: grid;
699
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
700
+ gap: 12px;
701
+ }
702
+
703
+ .action-item {
704
+ background: rgba(255,255,255,0.1);
705
+ border: 1px solid rgba(255,255,255,0.1);
706
+ border-radius: var(--radius-sm);
707
+ padding: 16px;
708
+ }
709
+
710
+ .action-item h4 {
711
+ font-size: 13px;
712
+ font-weight: 600;
713
+ margin-bottom: 8px;
714
+ opacity: 0.9;
715
+ }
716
+
717
+ .action-item code {
718
+ display: block;
719
+ background: rgba(0,0,0,0.3);
720
+ padding: 8px 12px;
721
+ border-radius: 4px;
722
+ font-family: 'Monaco', 'Consolas', monospace;
723
+ font-size: 12px;
724
+ color: #60a5fa;
725
+ }
726
+
727
+ /* Footer */
728
+ .footer {
729
+ text-align: center;
730
+ padding: 40px 24px;
731
+ border-top: 1px solid var(--color-border);
732
+ margin-top: 40px;
733
+ }
734
+
735
+ .footer p {
736
+ font-size: 12px;
737
+ color: var(--color-text-secondary);
738
+ margin-bottom: 8px;
739
+ }
740
+
741
+ /* Responsive */
742
+ @media (max-width: 768px) {
743
+ .container {
744
+ padding: 16px;
745
+ }
746
+
747
+ .header {
748
+ padding: 20px;
749
+ }
750
+
751
+ .grade-section {
752
+ flex-direction: column;
753
+ text-align: center;
754
+ }
755
+
756
+ .stats-grid {
757
+ grid-template-columns: repeat(2, 1fr);
758
+ }
759
+
760
+ .finding-content {
761
+ padding-left: 20px;
762
+ }
763
+
764
+ .target-meta {
765
+ flex-direction: column;
766
+ gap: 12px;
767
+ }
768
+ }
769
+
770
+ @media print {
771
+ body { background: white; }
772
+ .finding-content { display: block !important; }
773
+ .header { background: #3b82f6 !important; -webkit-print-color-adjust: exact; }
774
+ }
775
+ </style>
776
+ </head>
777
+ <body>
778
+ <div class="container">
779
+ <!-- Header with Grade -->
780
+ <div class="header">
781
+ <div class="header-top">
782
+ <div class="brand">
783
+ <div class="logo">S</div>
784
+ <div class="brand-text">
785
+ <h1>SupaSec Security Audit</h1>
786
+ <p>Enterprise-grade security assessment</p>
787
+ </div>
788
+ </div>
789
+ <div class="report-meta">
790
+ <div class="report-id">ID: scan_2026-01-28T19-49-18</div>
791
+ <div class="report-date">29/1/2026, 1:19:18 am</div>
792
+ </div>
793
+ </div>
794
+
795
+ <div class="grade-section">
796
+ <div class="grade-circle">
797
+ <div class="grade-letter">C</div>
798
+ <div class="grade-score">75/100</div>
799
+ </div>
800
+ <div class="grade-info">
801
+ <h2>Security Grade C</h2>
802
+ <p>Average security posture. Some issues need attention to improve your security grade.</p>
803
+ <div class="security-meter">
804
+ <div class="security-meter-fill"></div>
805
+ </div>
806
+ <div class="security-meter-labels">
807
+ <span>0</span>
808
+ <span>Security Score: 75</span>
809
+ <span>100</span>
810
+ </div>
811
+ </div>
812
+ </div>
813
+ </div>
814
+
815
+ <!-- Target Info -->
816
+ <div class="target-card">
817
+ <h3>Target</h3>
818
+ <div class="target-url">audityour.app</div>
819
+ <div class="target-meta">
820
+ <div class="target-meta-item">
821
+ <span>Scan Mode</span>
822
+ <span>URL Analysis</span>
823
+ </div>
824
+ <div class="target-meta-item">
825
+ <span>Duration</span>
826
+ <span>0.07s</span>
827
+ </div>
828
+ <div class="target-meta-item">
829
+ <span>Findings</span>
830
+ <span>3 issues detected</span>
831
+ </div>
832
+ <div class="target-meta-item">
833
+ <span>Passed Checks</span>
834
+ <span>0 checks passed</span>
835
+ </div>
836
+ </div>
837
+ </div>
838
+
839
+ <!-- Stats Grid -->
840
+ <div class="stats-grid">
841
+ <div class="stat-card">
842
+ <div class="stat-icon critical">🚨</div>
843
+ <div class="stat-value critical">0</div>
844
+ <div class="stat-label">Critical</div>
845
+ </div>
846
+ <div class="stat-card">
847
+ <div class="stat-icon high">⚠️</div>
848
+ <div class="stat-value high">2</div>
849
+ <div class="stat-label">High</div>
850
+ </div>
851
+ <div class="stat-card">
852
+ <div class="stat-icon medium">⚡</div>
853
+ <div class="stat-value medium">1</div>
854
+ <div class="stat-label">Medium</div>
855
+ </div>
856
+ <div class="stat-card">
857
+ <div class="stat-icon low">ℹ️</div>
858
+ <div class="stat-value low">0</div>
859
+ <div class="stat-label">Low</div>
860
+ </div>
861
+ </div>
862
+
863
+ <!-- Category Scores -->
864
+ <div class="category-section">
865
+ <h2>📊 Category Breakdown</h2>
866
+ <div class="category-grid">
867
+
868
+ </div>
869
+ </div>
870
+
871
+ <!-- Findings -->
872
+
873
+ <div class="findings-section">
874
+ <div class="section-header">
875
+ <div>
876
+ <h2>🔍 Security Findings</h2>
877
+ <p>3 security issues identified across 2 severity levels</p>
878
+ </div>
879
+ </div>
880
+ <div class="finding-card">
881
+ <div class="finding-header">
882
+ <div class="finding-severity high">⚠️</div>
883
+ <div class="finding-title-section">
884
+ <div class="finding-title">
885
+ JWT Token Exposed
886
+ <span class="finding-id">SEC-003</span>
887
+ </div>
888
+ <div class="finding-preview">Found jwt token in javascript content. JWT token detected</div>
889
+ <div class="finding-meta">
890
+ <span class="finding-badge high">HIGH</span>
891
+ <span class="finding-badge finding-category">secrets</span>
892
+ <span class="finding-badge" style="background: #f3f4f6; color: #4b5563;">📍 audityour.app:3</span>
893
+ </div>
894
+ </div>
895
+ <div class="finding-toggle">▼</div>
896
+ </div>
897
+ <div class="finding-content">
898
+
899
+ <div class="finding-content-section">
900
+ <h4>Description</h4>
901
+ <p>Found jwt token in javascript content. JWT token detected</p>
902
+ </div>
903
+ <div class="finding-content-section">
904
+ <h4>Impact</h4>
905
+ <p>Authentication token exposure - unauthorized access to user accounts</p>
906
+
907
+ <div style="margin-top: 12px;">
908
+ <span style="font-size: 12px; color: var(--color-text-secondary);">Compliance Violations: </span>
909
+ <span style="font-size: 11px; background: #fef3c7; color: #92400e; padding: 2px 8px; border-radius: 4px; margin-right: 4px;">SOC2-CC6.1</span><span style="font-size: 11px; background: #fef3c7; color: #92400e; padding: 2px 8px; border-radius: 4px; margin-right: 4px;">OWASP-A02-2021</span>
910
+ </div>
911
+ </div>
912
+ <div class="finding-content-section">
913
+ <h4>Remediation</h4>
914
+ <p>Remove jwt token from client-side code</p>
915
+
916
+ <ul style="margin-top: 12px;">
917
+ <li>Remove the exposed secret from client-side code immediately</li><li>Move the secret to environment variables on the server</li><li>Regenerate the exposed secret to invalidate the compromised key</li><li>Use only the anon/public key in frontend code</li>
918
+ </ul>
919
+
920
+ </div>
921
+ <div class="finding-content-section">
922
+ <h4>Technical Details</h4>
923
+ <div class="tech-details">
924
+ <div class="tech-row">
925
+ <div class="tech-label">Exposed Key</div>
926
+ <div class="tech-value">eyJh**************************************************iJ9.</div>
927
+ </div>
928
+ <div class="tech-row">
929
+ <div class="tech-label">Key Type</div>
930
+ <div class="tech-value">JWT Token</div>
931
+ </div>
932
+ <div class="tech-row">
933
+ <div class="tech-label">Location</div>
934
+ <div class="tech-value">audityour.app:3</div>
935
+ </div>
936
+ <div class="tech-row" style="flex-direction: column;">
937
+ <div class="tech-label" style="margin-bottom: 8px;">Code Snippet</div>
938
+ <div class="code-block" style="margin: 0;">
939
+ <pre><code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiJ9.</code></pre>
940
+ </div>
941
+ </div>
942
+ </div>
943
+ </div>
944
+ </div>
945
+ </div>
946
+ <div class="finding-card">
947
+ <div class="finding-header">
948
+ <div class="finding-severity high">⚠️</div>
949
+ <div class="finding-title-section">
950
+ <div class="finding-title">
951
+ HTTPS Analysis Failed
952
+ <span class="finding-id">SEC-HTTPS-ERR</span>
953
+ </div>
954
+ <div class="finding-preview">Failed to analyze HTTPS configuration: Invalid URL</div>
955
+ <div class="finding-meta">
956
+ <span class="finding-badge high">HIGH</span>
957
+ <span class="finding-badge finding-category">transport</span>
958
+ <span class="finding-badge" style="background: #f3f4f6; color: #4b5563;">📍 audityour.app</span>
959
+ </div>
960
+ </div>
961
+ <div class="finding-toggle">▼</div>
962
+ </div>
963
+ <div class="finding-content">
964
+
965
+ <div class="finding-content-section">
966
+ <h4>Description</h4>
967
+ <p>Failed to analyze HTTPS configuration: Invalid URL</p>
968
+ </div>
969
+ <div class="finding-content-section">
970
+ <h4>Impact</h4>
971
+ <p>Failed to analyze HTTPS configuration: Invalid URL</p>
972
+
973
+ </div>
974
+ <div class="finding-content-section">
975
+ <h4>Remediation</h4>
976
+ <p>Verify the target URL is correct and accessible.</p>
977
+
978
+
979
+ </div>
980
+ <div class="finding-content-section">
981
+ <h4>Technical Details</h4>
982
+ <div class="tech-details">
983
+ <div class="tech-row">
984
+ <div class="tech-label">Location</div>
985
+ <div class="tech-value">audityour.app</div>
986
+ </div>
987
+ </div>
988
+ </div>
989
+ </div>
990
+ </div>
991
+ <div class="finding-card">
992
+ <div class="finding-header">
993
+ <div class="finding-severity medium">⚡</div>
994
+ <div class="finding-title-section">
995
+ <div class="finding-title">
996
+ Supabase Anon Key Exposed
997
+ <span class="finding-id">SEC-001</span>
998
+ </div>
999
+ <div class="finding-preview">Found supabase anon key in javascript content. Anonymous key with public access - limited by RLS policies
1000
+
1001
+ Permission Le...</div>
1002
+ <div class="finding-meta">
1003
+ <span class="finding-badge medium">MEDIUM</span>
1004
+ <span class="finding-badge finding-category">secrets</span>
1005
+ <span class="finding-badge" style="background: #f3f4f6; color: #4b5563;">📍 audityour.app:3</span>
1006
+ </div>
1007
+ </div>
1008
+ <div class="finding-toggle">▼</div>
1009
+ </div>
1010
+ <div class="finding-content">
1011
+
1012
+ <div class="finding-content-section">
1013
+ <h4>Description</h4>
1014
+ <p>Found supabase anon key in javascript content. Anonymous key with public access - limited by RLS policies
1015
+
1016
+ Permission Level: Anonymous Key - Public access with RLS restrictions
1017
+
1018
+ Potential Risks:
1019
+ • Access limited by RLS policies
1020
+ • Can sign up new users
1021
+ • Can access public data
1022
+ • Low risk if RLS properly configured</p>
1023
+ </div>
1024
+ <div class="finding-content-section">
1025
+ <h4>Impact</h4>
1026
+ <p>Complete database access - attacker can read, write, and delete all data</p>
1027
+
1028
+ <div style="margin-top: 12px;">
1029
+ <span style="font-size: 12px; color: var(--color-text-secondary);">Compliance Violations: </span>
1030
+ <span style="font-size: 11px; background: #fef3c7; color: #92400e; padding: 2px 8px; border-radius: 4px; margin-right: 4px;">SOC2-CC6.1</span><span style="font-size: 11px; background: #fef3c7; color: #92400e; padding: 2px 8px; border-radius: 4px; margin-right: 4px;">GDPR-Article-32</span>
1031
+ </div>
1032
+ </div>
1033
+ <div class="finding-content-section">
1034
+ <h4>Remediation</h4>
1035
+ <p>Remove supabase anon key from client-side code</p>
1036
+
1037
+ <ul style="margin-top: 12px;">
1038
+ <li>Regenerate the service_role key in Supabase dashboard</li><li>Move service_role key to backend environment variables only</li><li>Use anon key for client-side operations</li><li>Review database access logs for unauthorized access</li>
1039
+ </ul>
1040
+
1041
+ </div>
1042
+ <div class="finding-content-section">
1043
+ <h4>Technical Details</h4>
1044
+ <div class="tech-details">
1045
+ <div class="tech-row">
1046
+ <div class="tech-label">Exposed Key</div>
1047
+ <div class="tech-value">eyJh**************************************************iJ9.</div>
1048
+ </div>
1049
+ <div class="tech-row">
1050
+ <div class="tech-label">Key Type</div>
1051
+ <div class="tech-value">Supabase Anon Key</div>
1052
+ </div>
1053
+ <div class="tech-row">
1054
+ <div class="tech-label">Location</div>
1055
+ <div class="tech-value">audityour.app:3</div>
1056
+ </div>
1057
+ <div class="tech-row" style="flex-direction: column;">
1058
+ <div class="tech-label" style="margin-bottom: 8px;">Code Snippet</div>
1059
+ <div class="code-block" style="margin: 0;">
1060
+ <pre><code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiJ9.</code></pre>
1061
+ </div>
1062
+ </div>
1063
+ </div>
1064
+ </div>
1065
+ </div>
1066
+ </div></div>
1067
+
1068
+ <!-- Passed Checks -->
1069
+
1070
+
1071
+ <!-- Quick Actions -->
1072
+ <div class="actions-section">
1073
+ <h2>🛠️ Quick Actions</h2>
1074
+ <div class="actions-grid">
1075
+ <div class="action-item">
1076
+ <h4>Fix Critical Issues</h4>
1077
+ <code>supasec fix --interactive</code>
1078
+ </div>
1079
+ <div class="action-item">
1080
+ <h4>Export as JSON</h4>
1081
+ <code>supasec scan --format json</code>
1082
+ </div>
1083
+ <div class="action-item">
1084
+ <h4>Save Snapshot</h4>
1085
+ <code>supasec snapshot save</code>
1086
+ </div>
1087
+ <div class="action-item">
1088
+ <h4>Deep Scan</h4>
1089
+ <code>supasec scan --deep</code>
1090
+ </div>
1091
+ </div>
1092
+ </div>
1093
+
1094
+ <!-- Footer -->
1095
+ <div class="footer">
1096
+ <p>Generated by SupaSec v1.0.4 • Report ID: scan_2026-01-28T19-49-18</p>
1097
+ <p>SupaSec is an independent security auditing tool and is not affiliated with Supabase Inc.</p>
1098
+ </div>
1099
+ </div>
1100
+
1101
+ <script>
1102
+ // Toggle finding details
1103
+ document.querySelectorAll('.finding-header').forEach(header => {
1104
+ header.addEventListener('click', () => {
1105
+ const content = header.nextElementSibling;
1106
+ const toggle = header.querySelector('.finding-toggle');
1107
+ content.classList.toggle('active');
1108
+ toggle.style.transform = content.classList.contains('active') ? 'rotate(180deg)' : 'rotate(0deg)';
1109
+ });
1110
+ });
1111
+
1112
+ // Animate progress bars on load
1113
+ window.addEventListener('load', () => {
1114
+ document.querySelectorAll('.category-bar-fill').forEach(bar => {
1115
+ const width = bar.style.width;
1116
+ bar.style.width = '0';
1117
+ setTimeout(() => bar.style.width = width, 100);
1118
+ });
1119
+ });
1120
+ </script>
1121
+ </body>
1122
+ </html>