Skip to content

Commit 801eefd

Browse files
fix: lint and typechecks (#2)
* fix: lint and typechecks * fix: add validate on pr to main * fix: major haul of lint errors * fix: final typecheck tidbits
1 parent 0c05205 commit 801eefd

21 files changed

+2724
-1424
lines changed

.github/workflows/validate.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ on:
55
branches:
66
- 'main'
77
workflow_call:
8+
pull_request:
9+
branches:
10+
- 'main'
811

912
concurrency:
1013
group: validate-${{ github.ref_name }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,4 @@ storybook-static
150150
.tmp/
151151
.temp/
152152
.claude/
153+
private.pem

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
"@caido/eslint-config": "^0.5.0",
1414
"@caido/tailwindcss": "0.0.1",
1515
"@vitejs/plugin-vue": "5.2.1",
16+
"eslint": "^9.35.0",
17+
"lodash": "^4.17.21",
1618
"postcss-prefixwrap": "1.51.0",
1719
"tailwindcss": "3.4.13",
1820
"tailwindcss-primeui": "0.3.4",

packages/backend/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"typecheck": "tsc --noEmit"
88
},
99
"devDependencies": {
10-
"@caido/sdk-backend": "^0.46.0"
10+
"@caido/sdk-backend": "^0.46.0",
11+
"@types/node": "^24.3.1"
1112
}
1213
}

packages/backend/src/blacklists.ts

Lines changed: 83 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,80 @@ export const USER_CONTENT_HOSTS = [
2424
"googleusercontent.com",
2525

2626
// Blogger - Comprehensive subdomain list
27-
"*.blogspot.ae", "*.blogspot.al", "*.blogspot.am", "*.blogspot.ba", "*.blogspot.be",
28-
"*.blogspot.bg", "*.blogspot.bj", "*.blogspot.ca", "*.blogspot.cf", "*.blogspot.ch",
29-
"*.blogspot.cl", "*.blogspot.co.at", "*.blogspot.co.id", "*.blogspot.co.il",
30-
"*.blogspot.co.ke", "*.blogspot.co.nz", "*.blogspot.co.uk", "*.blogspot.co.za",
31-
"*.blogspot.com", "*.blogspot.com.ar", "*.blogspot.com.au", "*.blogspot.com.br",
32-
"*.blogspot.com.by", "*.blogspot.com.co", "*.blogspot.com.cy", "*.blogspot.com.ee",
33-
"*.blogspot.com.eg", "*.blogspot.com.es", "*.blogspot.com.mt", "*.blogspot.com.ng",
34-
"*.blogspot.com.tr", "*.blogspot.com.uy", "*.blogspot.cv", "*.blogspot.cz",
35-
"*.blogspot.de", "*.blogspot.dk", "*.blogspot.fi", "*.blogspot.fr", "*.blogspot.gr",
36-
"*.blogspot.hk", "*.blogspot.hr", "*.blogspot.hu", "*.blogspot.ie", "*.blogspot.in",
37-
"*.blogspot.is", "*.blogspot.it", "*.blogspot.jp", "*.blogspot.kr", "*.blogspot.li",
38-
"*.blogspot.lt", "*.blogspot.lu", "*.blogspot.md", "*.blogspot.mk", "*.blogspot.mr",
39-
"*.blogspot.mx", "*.blogspot.my", "*.blogspot.nl", "*.blogspot.no", "*.blogspot.pe",
40-
"*.blogspot.pt", "*.blogspot.qa", "*.blogspot.re", "*.blogspot.ro", "*.blogspot.rs",
41-
"*.blogspot.ru", "*.blogspot.se", "*.blogspot.sg", "*.blogspot.si", "*.blogspot.sk",
42-
"*.blogspot.sn", "*.blogspot.td", "*.blogspot.tw", "*.blogspot.ug", "*.blogspot.vn"
27+
"*.blogspot.ae",
28+
"*.blogspot.al",
29+
"*.blogspot.am",
30+
"*.blogspot.ba",
31+
"*.blogspot.be",
32+
"*.blogspot.bg",
33+
"*.blogspot.bj",
34+
"*.blogspot.ca",
35+
"*.blogspot.cf",
36+
"*.blogspot.ch",
37+
"*.blogspot.cl",
38+
"*.blogspot.co.at",
39+
"*.blogspot.co.id",
40+
"*.blogspot.co.il",
41+
"*.blogspot.co.ke",
42+
"*.blogspot.co.nz",
43+
"*.blogspot.co.uk",
44+
"*.blogspot.co.za",
45+
"*.blogspot.com",
46+
"*.blogspot.com.ar",
47+
"*.blogspot.com.au",
48+
"*.blogspot.com.br",
49+
"*.blogspot.com.by",
50+
"*.blogspot.com.co",
51+
"*.blogspot.com.cy",
52+
"*.blogspot.com.ee",
53+
"*.blogspot.com.eg",
54+
"*.blogspot.com.es",
55+
"*.blogspot.com.mt",
56+
"*.blogspot.com.ng",
57+
"*.blogspot.com.tr",
58+
"*.blogspot.com.uy",
59+
"*.blogspot.cv",
60+
"*.blogspot.cz",
61+
"*.blogspot.de",
62+
"*.blogspot.dk",
63+
"*.blogspot.fi",
64+
"*.blogspot.fr",
65+
"*.blogspot.gr",
66+
"*.blogspot.hk",
67+
"*.blogspot.hr",
68+
"*.blogspot.hu",
69+
"*.blogspot.ie",
70+
"*.blogspot.in",
71+
"*.blogspot.is",
72+
"*.blogspot.it",
73+
"*.blogspot.jp",
74+
"*.blogspot.kr",
75+
"*.blogspot.li",
76+
"*.blogspot.lt",
77+
"*.blogspot.lu",
78+
"*.blogspot.md",
79+
"*.blogspot.mk",
80+
"*.blogspot.mr",
81+
"*.blogspot.mx",
82+
"*.blogspot.my",
83+
"*.blogspot.nl",
84+
"*.blogspot.no",
85+
"*.blogspot.pe",
86+
"*.blogspot.pt",
87+
"*.blogspot.qa",
88+
"*.blogspot.re",
89+
"*.blogspot.ro",
90+
"*.blogspot.rs",
91+
"*.blogspot.ru",
92+
"*.blogspot.se",
93+
"*.blogspot.sg",
94+
"*.blogspot.si",
95+
"*.blogspot.sk",
96+
"*.blogspot.sn",
97+
"*.blogspot.td",
98+
"*.blogspot.tw",
99+
"*.blogspot.ug",
100+
"*.blogspot.vn",
43101
];
44102

45103
// JavaScript hosts with known vulnerable libraries
@@ -57,7 +115,12 @@ export const VULNERABLE_JS_HOSTS = [
57115
},
58116
{
59117
domain: "ajax.googleapis.com",
60-
paths: ["/ajax/libs/angularjs/", "/ajax/libs/yui/", "/jsapi", "/ajax/services/feed/find"],
118+
paths: [
119+
"/ajax/libs/angularjs/",
120+
"/ajax/libs/yui/",
121+
"/jsapi",
122+
"/ajax/services/feed/find",
123+
],
61124
risk: "AngularJS and JSONP vulnerabilities",
62125
},
63126

@@ -113,7 +176,8 @@ export class BlacklistManager {
113176

114177
// Check if path matches any vulnerable paths
115178
if (
116-
path &&
179+
path !== undefined &&
180+
path.trim() !== "" &&
117181
vulnHost.paths.some((vulnPath) => path.includes(vulnPath))
118182
) {
119183
return { isVulnerable: true, risk: vulnHost.risk };
@@ -144,7 +208,7 @@ export class BlacklistManager {
144208
results.push({
145209
type: "vulnerable-js",
146210
risk:
147-
vulnCheck.risk ||
211+
vulnCheck.risk ??
148212
"Domain hosts known vulnerable JavaScript libraries",
149213
});
150214
}
Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,44 @@
11
// CSP bypass database generated from data/csp-bypass-data.tsv
22
// This file is auto-generated - do not edit manually
33

4-
import { readFileSync } from 'fs';
5-
import { join } from 'path';
4+
import { readFileSync } from "fs";
5+
import { dirname, join } from "path";
6+
import { fileURLToPath } from "url";
67

7-
let cachedData: string | null = null;
8-
let cachedCount: number | null = null;
8+
let cachedData: string | undefined = undefined;
9+
let cachedCount: number | undefined = undefined;
910

1011
export const getCSPBypassData = (): string => {
11-
if (cachedData === null) {
12+
if (cachedData === undefined) {
1213
try {
1314
// Read the TSV file from the project root
14-
const tsvPath = join(process.cwd(), 'data', 'csp-bypass-data.tsv');
15-
cachedData = readFileSync(tsvPath, 'utf-8');
15+
const tsvPath = join(process.cwd(), "data", "csp-bypass-data.tsv");
16+
cachedData = readFileSync(tsvPath, "utf-8");
1617
} catch (error) {
1718
// Fallback to relative paths
1819
try {
19-
const tsvPath = join(__dirname, '..', '..', '..', 'data', 'csp-bypass-data.tsv');
20-
cachedData = readFileSync(tsvPath, 'utf-8');
20+
const currentDir = dirname(fileURLToPath(import.meta.url));
21+
const tsvPath = join(
22+
currentDir,
23+
"..",
24+
"..",
25+
"..",
26+
"data",
27+
"csp-bypass-data.tsv",
28+
);
29+
cachedData = readFileSync(tsvPath, "utf-8");
2130
} catch (fallbackError) {
2231
// Final fallback to absolute path
2332
try {
24-
cachedData = readFileSync('/Users/ads/git/csp-auditor/data/csp-bypass-data.tsv', 'utf-8');
33+
cachedData = readFileSync(
34+
"/Users/ads/git/csp-auditor/data/csp-bypass-data.tsv",
35+
"utf-8",
36+
);
2537
} catch (finalError) {
26-
console.error('Failed to load TSV data from all paths:', finalError);
27-
cachedData = 'Domain\tCode\n'; // Empty TSV with header
38+
console.error(
39+
"Failed to load TSV data from all paths: " + String(finalError),
40+
);
41+
cachedData = "Domain\tCode\n"; // Empty TSV with header
2842
}
2943
}
3044
}
@@ -33,14 +47,14 @@ export const getCSPBypassData = (): string => {
3347
};
3448

3549
export const getBypassCount = (): number => {
36-
if (cachedCount === null) {
50+
if (cachedCount === undefined) {
3751
const data = getCSPBypassData();
38-
const lines = data.trim().split('\n');
52+
const lines = data.trim().split("\n");
3953
cachedCount = Math.max(0, lines.length - 1); // Subtract 1 for header
4054
}
4155
return cachedCount;
4256
};
4357

4458
// Legacy exports for backward compatibility
4559
export const CSP_BYPASS_DATA = getCSPBypassData();
46-
export const BYPASS_COUNT = getBypassCount();
60+
export const BYPASS_COUNT = getBypassCount();

packages/backend/src/csp-parser.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export class CspParser {
7777
if (parts.length === 0) continue;
7878

7979
const directiveName = parts[0]?.toLowerCase();
80-
if (!directiveName) continue;
80+
if (directiveName === undefined || directiveName.trim() === "") continue;
8181
const directiveValues = parts.slice(1);
8282

8383
const directive: CspDirective = {
@@ -187,14 +187,14 @@ export class CspParser {
187187
}
188188
}
189189

190-
static computeEffectivePolicy(policies: CspPolicy[]): CspPolicy | null {
191-
if (policies.length === 0) return null;
192-
if (policies.length === 1) return policies[0] ?? null;
190+
static computeEffectivePolicy(policies: CspPolicy[]): CspPolicy | undefined {
191+
if (policies.length === 0) return undefined;
192+
if (policies.length === 1) return policies[0] ?? undefined;
193193

194194
// For multiple policies, we need to intersect the directives
195195
// This is a simplified approach - real CSP combination is complex
196196
const firstPolicy = policies[0];
197-
if (!firstPolicy) return null;
197+
if (!firstPolicy) return undefined;
198198

199199
const effectivePolicy = { ...firstPolicy };
200200
effectivePolicy.id = generateId();

0 commit comments

Comments
 (0)