Skip to content

Commit 519dc49

Browse files
fix: final typecheck tidbits
1 parent 4f306bb commit 519dc49

2 files changed

Lines changed: 87 additions & 64 deletions

File tree

packages/frontend/src/data/bypass-payloads.ts

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,31 @@ export interface BypassPayload {
1010
source: "cspbypass" | "generic";
1111
}
1212

13+
interface DatabaseEntry {
14+
id: string;
15+
technique: string;
16+
code: string;
17+
domain: string;
18+
}
19+
20+
function isDatabaseEntry(entry: unknown): entry is DatabaseEntry {
21+
if (typeof entry !== "object" || entry === null) {
22+
return false;
23+
}
24+
25+
const obj = entry as Record<string, unknown>;
26+
return (
27+
"id" in obj &&
28+
"technique" in obj &&
29+
"code" in obj &&
30+
"domain" in obj &&
31+
typeof obj.id === "string" &&
32+
typeof obj.technique === "string" &&
33+
typeof obj.code === "string" &&
34+
typeof obj.domain === "string"
35+
);
36+
}
37+
1338
// Real bypass payloads from CSPBypass project (https://github.com/renniepak/CSPBypass)
1439
export const bypassPayloads: Record<string, BypassPayload[]> = {
1540
"script-wildcard": [
@@ -214,12 +239,12 @@ export const getBypassesForVulnerability = (
214239
// Combine curated bypasses with filtered database entries
215240
// Remove duplicates based on payload content
216241
const combined = [...specificBypasses];
217-
const existingPayloads = new Set(specificBypasses.map((bp) => bp.payload));
242+
const existingPayloads: string[] = specificBypasses.map((bp) => bp.payload);
218243

219244
for (const dbBypass of additionalBypasses) {
220-
if (!existingPayloads.has(dbBypass.payload)) {
245+
if (existingPayloads.indexOf(dbBypass.payload) === -1) {
221246
combined.push(dbBypass);
222-
existingPayloads.add(dbBypass.payload);
247+
existingPayloads.push(dbBypass.payload);
223248
}
224249
}
225250

@@ -236,6 +261,10 @@ const filterDatabaseByVulnerabilityType = (
236261
const filtered: BypassPayload[] = [];
237262

238263
for (const entry of database) {
264+
if (!isDatabaseEntry(entry)) {
265+
continue;
266+
}
267+
239268
let relevanceScore = 0;
240269
let difficulty: "easy" | "medium" | "hard" = "medium";
241270

@@ -244,27 +273,19 @@ const filterDatabaseByVulnerabilityType = (
244273
case "script-wildcard":
245274
case "script-unsafe-inline":
246275
if (
247-
typeof entry === "object" &&
248-
entry !== null &&
249-
"technique" in entry &&
250-
(entry.technique === "AngularJS" ||
251-
entry.technique === "Script Injection" ||
252-
entry.technique === "Event Handler" ||
253-
entry.technique === "Alpine.js" ||
254-
entry.technique === "HTMX")
276+
entry.technique === "AngularJS" ||
277+
entry.technique === "Script Injection" ||
278+
entry.technique === "Event Handler" ||
279+
entry.technique === "Alpine.js" ||
280+
entry.technique === "HTMX"
255281
) {
256282
relevanceScore = entry.technique === "AngularJS" ? 10 : 8;
257283
difficulty = entry.technique === "Event Handler" ? "easy" : "medium";
258284
}
259285
break;
260286

261287
case "jsonp-bypass-risk":
262-
if (
263-
typeof entry === "object" &&
264-
entry !== null &&
265-
"technique" in entry &&
266-
entry.technique === "JSONP"
267-
) {
288+
if (entry.technique === "JSONP") {
268289
relevanceScore = 10;
269290
difficulty = "easy";
270291
}
@@ -279,12 +300,8 @@ const filterDatabaseByVulnerabilityType = (
279300

280301
case "script-unsafe-eval":
281302
if (
282-
typeof entry === "object" &&
283-
entry !== null &&
284-
"technique" in entry &&
285-
"code" in entry &&
286-
(entry.technique === "Script Injection" ||
287-
(typeof entry.code === "string" && entry.code.includes("eval")))
303+
entry.technique === "Script Injection" ||
304+
entry.code.indexOf("eval") !== -1
288305
) {
289306
relevanceScore = 8;
290307
difficulty = "medium";
@@ -293,12 +310,8 @@ const filterDatabaseByVulnerabilityType = (
293310

294311
case "object-wildcard":
295312
if (
296-
typeof entry === "object" &&
297-
entry !== null &&
298-
"technique" in entry &&
299-
"code" in entry &&
300-
(entry.technique === "Iframe Injection" ||
301-
(typeof entry.code === "string" && entry.code.includes("<iframe")))
313+
entry.technique === "Iframe Injection" ||
314+
entry.code.indexOf("<iframe") !== -1
302315
) {
303316
relevanceScore = 8;
304317
difficulty = "medium";
@@ -307,12 +320,8 @@ const filterDatabaseByVulnerabilityType = (
307320

308321
case "style-unsafe-inline":
309322
if (
310-
typeof entry === "object" &&
311-
entry !== null &&
312-
"technique" in entry &&
313-
"code" in entry &&
314-
(entry.technique === "Link Preload" ||
315-
(typeof entry.code === "string" && entry.code.includes("<link")))
323+
entry.technique === "Link Preload" ||
324+
entry.code.indexOf("<link") !== -1
316325
) {
317326
relevanceScore = 8;
318327
difficulty = "medium";

packages/frontend/src/views/App.vue

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,21 @@ import {
1717
getDifficultyColor,
1818
} from "@/data/bypass-payloads";
1919
import { useSDK } from "@/plugins/sdk";
20-
import type { BypassEntry, CspAnalysisResult, CspStats } from "@/types";
20+
import type {
21+
BypassEntry,
22+
CspAnalysisResult,
23+
CspStats,
24+
CspVulnerability,
25+
} from "@/types";
26+
27+
interface CspCheck {
28+
id: string;
29+
enabled: boolean;
30+
name: string;
31+
category: string;
32+
severity: string;
33+
description: string;
34+
}
2135
2236
const sdk = useSDK();
2337
@@ -26,7 +40,7 @@ const stats = ref<CspStats>({
2640
totalVulnerabilities: 0,
2741
severityStats: { high: 0, medium: 0, low: 0, info: 0 },
2842
typeStats: {},
29-
lastAnalyzed: null,
43+
lastAnalyzed: undefined,
3044
});
3145
3246
const allAnalyses = ref<CspAnalysisResult[]>([]);
@@ -202,7 +216,7 @@ const activeTab = ref(0);
202216
203217
// Modal state for vulnerability details
204218
const showVulnerabilityModal = ref(false);
205-
const selectedVulnerability = ref<unknown>(undefined);
219+
const selectedVulnerability = ref<CspVulnerability | undefined>(undefined);
206220
const selectedAnalysisForModal = ref<CspAnalysisResult | undefined>(undefined);
207221
208222
// CSP Bypass data
@@ -246,8 +260,7 @@ const calculateStatsFromAnalyses = (analyses: CspAnalysisResult[]) => {
246260
247261
const typeStats: Record<string, number> = {};
248262
for (const vuln of allVulnerabilities) {
249-
typeStats[vuln.type] =
250-
(typeof typeStats[vuln.type] === "number" ? typeStats[vuln.type] : 0) + 1;
263+
typeStats[vuln.type] = (typeStats[vuln.type] ?? 0) + 1;
251264
}
252265
253266
return {
@@ -275,7 +288,7 @@ const loadDashboardData = async () => {
275288
totalVulnerabilities: allStats.totalVulnerabilities,
276289
severityStats: allStats.severityStats,
277290
typeStats: allStats.typeStats,
278-
lastAnalyzed: allAnalyses.value.length > 0 ? new Date() : null,
291+
lastAnalyzed: allAnalyses.value.length > 0 ? new Date() : undefined,
279292
};
280293
} catch (error) {
281294
console.error("Failed to load dashboard data:", error);
@@ -423,7 +436,7 @@ const formatDate = (date: Date | string) => {
423436
const extractHostAndPath = (analysis: CspAnalysisResult) => {
424437
const firstPolicy = analysis.policies[0];
425438
426-
if (firstPolicy?.url !== null && firstPolicy.url.trim() !== "") {
439+
if (firstPolicy?.url !== undefined && firstPolicy.url.trim() !== "") {
427440
try {
428441
let urlToparse = firstPolicy.url;
429442
if (
@@ -439,8 +452,8 @@ const extractHostAndPath = (analysis: CspAnalysisResult) => {
439452
path: url.pathname || "/",
440453
};
441454
} catch (error) {
442-
const parts = firstPolicy.url.split("/");
443-
if (parts.length >= 1) {
455+
const parts = firstPolicy.url?.split("/") ?? [];
456+
if (parts.length > 0) {
444457
const firstPart = parts[0];
445458
let hostPart = "N/A";
446459
if (
@@ -478,16 +491,16 @@ const getSeverityPercentage = computed(() => {
478491
});
479492
480493
// Convert settings object to array for table display
481-
const cspChecksArray = computed(() => {
494+
const cspChecksArray = computed((): CspCheck[] => {
482495
return Object.entries(cspCheckSettings.value).map(([key, check]) => ({
483496
id: key,
484497
...check,
485498
}));
486499
});
487500
488501
// Group checks by category
489-
const checksByCategory = computed(() => {
490-
const grouped: Record<string, unknown[]> = {};
502+
const checksByCategory = computed((): Record<string, CspCheck[]> => {
503+
const grouped: Record<string, CspCheck[]> = {};
491504
cspChecksArray.value.forEach((check) => {
492505
if (!grouped[check.category]) {
493506
grouped[check.category] = [];
@@ -577,7 +590,7 @@ const saveCspCheckSettings = async () => {
577590
578591
// Modal functions
579592
const showVulnerabilityDetails = (
580-
vulnerability: unknown,
593+
vulnerability: CspVulnerability,
581594
analysis: CspAnalysisResult,
582595
) => {
583596
selectedVulnerability.value = vulnerability;
@@ -587,8 +600,8 @@ const showVulnerabilityDetails = (
587600
588601
const closeVulnerabilityModal = () => {
589602
showVulnerabilityModal.value = false;
590-
selectedVulnerability.value = null;
591-
selectedAnalysisForModal.value = null;
603+
selectedVulnerability.value = undefined;
604+
selectedAnalysisForModal.value = undefined;
592605
};
593606
594607
const getSeverityColor = (severity: string) => {
@@ -618,7 +631,7 @@ const paginatedAnalyses = computed(() => {
618631
619632
const viewAnalysisDetails = (analysisData: CspAnalysisResult) => {
620633
if (selectedAnalysis.value?.requestId === analysisData.requestId) {
621-
selectedAnalysis.value = null;
634+
selectedAnalysis.value = undefined;
622635
} else {
623636
selectedAnalysis.value = analysisData;
624637
}
@@ -741,18 +754,19 @@ const nextPage = () => {
741754
742755
// Helper function to safely update check settings
743756
const updateCheckSetting = (checkId: string, enabled: boolean) => {
744-
(
745-
cspCheckSettings.value as Record<
746-
string,
747-
{
748-
enabled: boolean;
749-
name: string;
750-
category: string;
751-
severity: string;
752-
description: string;
753-
}
754-
>
755-
)[checkId].enabled = enabled;
757+
const settings = cspCheckSettings.value as Record<
758+
string,
759+
{
760+
enabled: boolean;
761+
name: string;
762+
category: string;
763+
severity: string;
764+
description: string;
765+
}
766+
>;
767+
if (settings[checkId]) {
768+
settings[checkId].enabled = enabled;
769+
}
756770
};
757771
758772
const getCheckEnabled = (checkId: string): boolean => {
@@ -1972,7 +1986,7 @@ const getCheckEnabled = (checkId: string): boolean => {
19721986
<div class="space-y-2">
19731987
<div
19741988
v-for="vuln in selectedAnalysisForModal.vulnerabilities.filter(
1975-
(v) => v.id !== selectedVulnerability.id,
1989+
(v) => v.id !== selectedVulnerability?.id,
19761990
)"
19771991
:key="vuln.id"
19781992
class="flex items-center gap-3 p-2 bg-gray-50 dark:bg-gray-800 rounded cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"

0 commit comments

Comments
 (0)