@ucptools/validator 1.0.0 → 1.0.1
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.
- package/.claude/settings.local.json +60 -0
- package/.vercel/README.txt +11 -0
- package/.vercel/project.json +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +279 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/compliance/compliance-generator.d.ts +34 -0
- package/dist/compliance/compliance-generator.d.ts.map +1 -0
- package/dist/compliance/compliance-generator.js +320 -0
- package/dist/compliance/compliance-generator.js.map +1 -0
- package/dist/compliance/index.d.ts +8 -0
- package/dist/compliance/index.d.ts.map +1 -0
- package/dist/compliance/index.js +17 -0
- package/dist/compliance/index.js.map +1 -0
- package/dist/compliance/templates.d.ts +34 -0
- package/dist/compliance/templates.d.ts.map +1 -0
- package/{src/compliance/templates.ts → dist/compliance/templates.js} +117 -155
- package/dist/compliance/templates.js.map +1 -0
- package/dist/compliance/types.d.ts +64 -0
- package/dist/compliance/types.d.ts.map +1 -0
- package/dist/compliance/types.js +64 -0
- package/dist/compliance/types.js.map +1 -0
- package/dist/db/index.d.ts +11 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +63 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.d.ts +444 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +65 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/feed-analyzer/feed-analyzer.d.ts +26 -0
- package/dist/feed-analyzer/feed-analyzer.d.ts.map +1 -0
- package/{src/feed-analyzer/feed-analyzer.ts → dist/feed-analyzer/feed-analyzer.js} +642 -726
- package/dist/feed-analyzer/feed-analyzer.js.map +1 -0
- package/dist/feed-analyzer/index.d.ts +8 -0
- package/dist/feed-analyzer/index.d.ts.map +1 -0
- package/dist/feed-analyzer/index.js +19 -0
- package/dist/feed-analyzer/index.js.map +1 -0
- package/dist/feed-analyzer/types.d.ts +204 -0
- package/dist/feed-analyzer/types.d.ts.map +1 -0
- package/dist/feed-analyzer/types.js +162 -0
- package/dist/feed-analyzer/types.js.map +1 -0
- package/{src/generator/index.ts → dist/generator/index.d.ts} +1 -1
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +13 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/key-generator.d.ts +24 -0
- package/dist/generator/key-generator.d.ts.map +1 -0
- package/dist/generator/key-generator.js +144 -0
- package/dist/generator/key-generator.js.map +1 -0
- package/dist/generator/profile-builder.d.ts +15 -0
- package/dist/generator/profile-builder.d.ts.map +1 -0
- package/dist/generator/profile-builder.js +338 -0
- package/dist/generator/profile-builder.js.map +1 -0
- package/dist/hosting/artifacts-generator.d.ts +10 -0
- package/dist/hosting/artifacts-generator.d.ts.map +1 -0
- package/{src/hosting/artifacts-generator.ts → dist/hosting/artifacts-generator.js} +191 -241
- package/dist/hosting/artifacts-generator.js.map +1 -0
- package/{src/hosting/index.ts → dist/hosting/index.d.ts} +1 -1
- package/dist/hosting/index.d.ts.map +1 -0
- package/dist/hosting/index.js +10 -0
- package/dist/hosting/index.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/{src/security/index.ts → dist/security/index.d.ts} +8 -15
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +12 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/security-scanner.d.ts +10 -0
- package/dist/security/security-scanner.d.ts.map +1 -0
- package/dist/security/security-scanner.js +541 -0
- package/dist/security/security-scanner.js.map +1 -0
- package/dist/security/types.d.ts +48 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security/types.js +21 -0
- package/dist/security/types.js.map +1 -0
- package/dist/services/directory.d.ts +104 -0
- package/dist/services/directory.d.ts.map +1 -0
- package/dist/services/directory.js +333 -0
- package/dist/services/directory.js.map +1 -0
- package/dist/simulator/agent-simulator.d.ts +69 -0
- package/dist/simulator/agent-simulator.d.ts.map +1 -0
- package/{src/simulator/agent-simulator.ts → dist/simulator/agent-simulator.js} +650 -941
- package/dist/simulator/agent-simulator.js.map +1 -0
- package/{src/simulator/index.ts → dist/simulator/index.d.ts} +7 -7
- package/dist/simulator/index.d.ts.map +1 -0
- package/dist/simulator/index.js +23 -0
- package/dist/simulator/index.js.map +1 -0
- package/{src/simulator/types.ts → dist/simulator/types.d.ts} +145 -170
- package/dist/simulator/types.d.ts.map +1 -0
- package/dist/simulator/types.js +18 -0
- package/dist/simulator/types.js.map +1 -0
- package/dist/types/generator.d.ts +106 -0
- package/dist/types/generator.d.ts.map +1 -0
- package/dist/types/generator.js +6 -0
- package/dist/types/generator.js.map +1 -0
- package/{src/types/index.ts → dist/types/index.d.ts} +1 -1
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +23 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/ucp-profile.d.ts +103 -0
- package/dist/types/ucp-profile.d.ts.map +1 -0
- package/dist/types/ucp-profile.js +45 -0
- package/dist/types/ucp-profile.js.map +1 -0
- package/dist/types/validation.d.ts +68 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +32 -0
- package/dist/types/validation.js.map +1 -0
- package/dist/validator/index.d.ts +26 -0
- package/dist/validator/index.d.ts.map +1 -0
- package/dist/validator/index.js +161 -0
- package/dist/validator/index.js.map +1 -0
- package/dist/validator/network-validator.d.ts +28 -0
- package/dist/validator/network-validator.d.ts.map +1 -0
- package/dist/validator/network-validator.js +319 -0
- package/dist/validator/network-validator.js.map +1 -0
- package/dist/validator/rules-validator.d.ts +11 -0
- package/dist/validator/rules-validator.d.ts.map +1 -0
- package/dist/validator/rules-validator.js +257 -0
- package/dist/validator/rules-validator.js.map +1 -0
- package/dist/validator/sdk-validator.d.ts +58 -0
- package/dist/validator/sdk-validator.d.ts.map +1 -0
- package/{src/validator/sdk-validator.ts → dist/validator/sdk-validator.js} +273 -330
- package/dist/validator/sdk-validator.js.map +1 -0
- package/dist/validator/structural-validator.d.ts +11 -0
- package/dist/validator/structural-validator.d.ts.map +1 -0
- package/dist/validator/structural-validator.js +415 -0
- package/dist/validator/structural-validator.js.map +1 -0
- package/package.json +1 -1
- package/publish-output.txt +0 -0
- package/CLAUDE.md +0 -109
- package/api/analyze-feed.js +0 -140
- package/api/badge.js +0 -185
- package/api/benchmark.js +0 -177
- package/api/directory-stats.ts +0 -29
- package/api/directory.ts +0 -73
- package/api/generate-compliance.js +0 -143
- package/api/generate-schema.js +0 -457
- package/api/generate.js +0 -132
- package/api/security-scan.js +0 -133
- package/api/simulate.js +0 -187
- package/api/tsconfig.json +0 -10
- package/api/validate.js +0 -1351
- package/apify-actor/.actor/actor.json +0 -68
- package/apify-actor/.actor/input_schema.json +0 -32
- package/apify-actor/APIFY-STORE-LISTING.md +0 -412
- package/apify-actor/Dockerfile +0 -8
- package/apify-actor/README.md +0 -166
- package/apify-actor/main.ts +0 -111
- package/apify-actor/package.json +0 -17
- package/apify-actor/src/main.js +0 -199
- package/docs/BRAND-IDENTITY.md +0 -238
- package/docs/BRAND-STYLE-GUIDE.md +0 -356
- package/drizzle/0000_black_king_cobra.sql +0 -39
- package/drizzle/meta/0000_snapshot.json +0 -309
- package/drizzle/meta/_journal.json +0 -13
- package/drizzle.config.ts +0 -10
- package/public/.well-known/ucp +0 -25
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/brand.css +0 -321
- package/public/directory.html +0 -701
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/guides/bigcommerce.html +0 -743
- package/public/guides/fastucp.html +0 -838
- package/public/guides/magento.html +0 -779
- package/public/guides/shopify.html +0 -726
- package/public/guides/squarespace.html +0 -749
- package/public/guides/wix.html +0 -747
- package/public/guides/woocommerce.html +0 -733
- package/public/index.html +0 -3835
- package/public/learn.html +0 -396
- package/public/logo.jpeg +0 -0
- package/public/og-image-icon.png +0 -0
- package/public/og-image.png +0 -0
- package/public/robots.txt +0 -6
- package/public/site.webmanifest +0 -31
- package/public/sitemap.xml +0 -69
- package/public/social/linkedin-banner-1128x191.png +0 -0
- package/public/social/temp.PNG +0 -0
- package/public/social/x-header-1500x500.png +0 -0
- package/public/verify.html +0 -410
- package/scripts/generate-favicons.js +0 -44
- package/scripts/generate-ico.js +0 -23
- package/scripts/generate-og-image.js +0 -45
- package/scripts/reset-db.ts +0 -77
- package/scripts/seed-db.ts +0 -71
- package/scripts/setup-benchmark-db.js +0 -70
- package/src/api/server.ts +0 -266
- package/src/cli/index.ts +0 -302
- package/src/compliance/compliance-generator.ts +0 -452
- package/src/compliance/index.ts +0 -28
- package/src/compliance/types.ts +0 -170
- package/src/db/index.ts +0 -28
- package/src/db/schema.ts +0 -84
- package/src/feed-analyzer/index.ts +0 -34
- package/src/feed-analyzer/types.ts +0 -354
- package/src/generator/key-generator.ts +0 -124
- package/src/generator/profile-builder.ts +0 -402
- package/src/index.ts +0 -105
- package/src/security/security-scanner.ts +0 -604
- package/src/security/types.ts +0 -55
- package/src/services/directory.ts +0 -434
- package/src/types/generator.ts +0 -140
- package/src/types/ucp-profile.ts +0 -140
- package/src/types/validation.ts +0 -89
- package/src/validator/index.ts +0 -194
- package/src/validator/network-validator.ts +0 -417
- package/src/validator/rules-validator.ts +0 -297
- package/src/validator/structural-validator.ts +0 -476
- package/tests/fixtures/non-compliant-profile.json +0 -25
- package/tests/fixtures/official-sample-profile.json +0 -75
- package/tests/integration/benchmark.test.ts +0 -207
- package/tests/integration/database.test.ts +0 -163
- package/tests/integration/directory-api.test.ts +0 -268
- package/tests/integration/simulate-api.test.ts +0 -230
- package/tests/integration/validate-api.test.ts +0 -269
- package/tests/setup.ts +0 -15
- package/tests/unit/agent-simulator.test.ts +0 -575
- package/tests/unit/compliance-generator.test.ts +0 -374
- package/tests/unit/directory-service.test.ts +0 -272
- package/tests/unit/feed-analyzer.test.ts +0 -517
- package/tests/unit/lint-suggestions.test.ts +0 -423
- package/tests/unit/official-samples.test.ts +0 -211
- package/tests/unit/pdf-report.test.ts +0 -390
- package/tests/unit/sdk-validator.test.ts +0 -531
- package/tests/unit/security-scanner.test.ts +0 -410
- package/tests/unit/validation.test.ts +0 -390
- package/vercel.json +0 -34
- package/vitest.config.ts +0 -22
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Security Posture Scanner for UCP Endpoints
|
|
4
|
+
* Scans UCP endpoints for common security misconfigurations
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.scanEndpointSecurity = scanEndpointSecurity;
|
|
8
|
+
const types_js_1 = require("./types.js");
|
|
9
|
+
const DEFAULT_TIMEOUT_MS = 15000;
|
|
10
|
+
/**
|
|
11
|
+
* Run a full security scan on a UCP endpoint
|
|
12
|
+
*/
|
|
13
|
+
async function scanEndpointSecurity(domain, options = {}) {
|
|
14
|
+
const timeoutMs = options.timeoutMs || DEFAULT_TIMEOUT_MS;
|
|
15
|
+
const checks = [];
|
|
16
|
+
// Normalize domain
|
|
17
|
+
const normalizedDomain = domain.replace(/^https?:\/\//, '').replace(/\/.*$/, '');
|
|
18
|
+
const endpoint = `https://${normalizedDomain}/.well-known/ucp`;
|
|
19
|
+
// Run all security checks
|
|
20
|
+
checks.push(await checkHttpsRequired(normalizedDomain));
|
|
21
|
+
checks.push(await checkPrivateIp(normalizedDomain));
|
|
22
|
+
// Fetch the endpoint to analyze response
|
|
23
|
+
const response = await fetchEndpointSafely(endpoint, timeoutMs);
|
|
24
|
+
if (response.success && response.response && response.headers && response.body !== undefined) {
|
|
25
|
+
checks.push(await checkTlsVersion(endpoint, response.response));
|
|
26
|
+
checks.push(await checkCorsConfiguration(response.response, response.headers));
|
|
27
|
+
checks.push(await checkSecurityHeaders(response.headers));
|
|
28
|
+
checks.push(await checkContentType(response.headers));
|
|
29
|
+
checks.push(await checkRateLimiting(response.headers));
|
|
30
|
+
checks.push(await checkCacheHeaders(response.headers));
|
|
31
|
+
checks.push(await checkErrorDisclosure(response.body));
|
|
32
|
+
checks.push(checkResponseTime(response.responseTimeMs));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// Endpoint not reachable - add skip results
|
|
36
|
+
checks.push(createSkippedCheck(types_js_1.SecurityCheckIds.TLS_VERSION, 'TLS Version', 'Endpoint not reachable'));
|
|
37
|
+
checks.push(createSkippedCheck(types_js_1.SecurityCheckIds.CORS_CONFIG, 'CORS Configuration', 'Endpoint not reachable'));
|
|
38
|
+
checks.push(createSkippedCheck(types_js_1.SecurityCheckIds.SECURITY_HEADERS, 'Security Headers', 'Endpoint not reachable'));
|
|
39
|
+
checks.push(createSkippedCheck(types_js_1.SecurityCheckIds.CONTENT_TYPE, 'Content-Type', 'Endpoint not reachable'));
|
|
40
|
+
checks.push(createSkippedCheck(types_js_1.SecurityCheckIds.RATE_LIMITING, 'Rate Limiting', 'Endpoint not reachable'));
|
|
41
|
+
checks.push(createSkippedCheck(types_js_1.SecurityCheckIds.CACHE_HEADERS, 'Cache Headers', 'Endpoint not reachable'));
|
|
42
|
+
checks.push(createSkippedCheck(types_js_1.SecurityCheckIds.ERROR_DISCLOSURE, 'Error Disclosure', 'Endpoint not reachable'));
|
|
43
|
+
checks.push(createSkippedCheck(types_js_1.SecurityCheckIds.RESPONSE_TIME, 'Response Time', 'Endpoint not reachable'));
|
|
44
|
+
}
|
|
45
|
+
// Calculate score and grade
|
|
46
|
+
const summary = calculateSummary(checks);
|
|
47
|
+
const score = calculateScore(checks);
|
|
48
|
+
const grade = calculateGrade(score);
|
|
49
|
+
return {
|
|
50
|
+
domain: normalizedDomain,
|
|
51
|
+
endpoint,
|
|
52
|
+
scanned_at: new Date().toISOString(),
|
|
53
|
+
score,
|
|
54
|
+
grade,
|
|
55
|
+
checks,
|
|
56
|
+
summary,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Fetch endpoint safely with timeout
|
|
61
|
+
*/
|
|
62
|
+
async function fetchEndpointSafely(url, timeoutMs) {
|
|
63
|
+
const controller = new AbortController();
|
|
64
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
65
|
+
const startTime = Date.now();
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetch(url, {
|
|
68
|
+
signal: controller.signal,
|
|
69
|
+
headers: {
|
|
70
|
+
'Accept': 'application/json',
|
|
71
|
+
'User-Agent': 'UCP-Security-Scanner/1.0',
|
|
72
|
+
'Origin': 'https://ucptools.dev',
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
clearTimeout(timeoutId);
|
|
76
|
+
const responseTimeMs = Date.now() - startTime;
|
|
77
|
+
const body = await response.text();
|
|
78
|
+
return {
|
|
79
|
+
success: true,
|
|
80
|
+
response,
|
|
81
|
+
headers: response.headers,
|
|
82
|
+
body,
|
|
83
|
+
responseTimeMs,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
clearTimeout(timeoutId);
|
|
88
|
+
return {
|
|
89
|
+
success: false,
|
|
90
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check 1: HTTPS Required
|
|
96
|
+
*/
|
|
97
|
+
async function checkHttpsRequired(domain) {
|
|
98
|
+
// Try HTTP to see if it redirects or is accessible
|
|
99
|
+
try {
|
|
100
|
+
const controller = new AbortController();
|
|
101
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
|
102
|
+
const response = await fetch(`http://${domain}/.well-known/ucp`, {
|
|
103
|
+
signal: controller.signal,
|
|
104
|
+
redirect: 'manual',
|
|
105
|
+
headers: { 'User-Agent': 'UCP-Security-Scanner/1.0' },
|
|
106
|
+
});
|
|
107
|
+
clearTimeout(timeoutId);
|
|
108
|
+
// Check if HTTP redirects to HTTPS
|
|
109
|
+
if (response.status >= 300 && response.status < 400) {
|
|
110
|
+
const location = response.headers.get('location');
|
|
111
|
+
if (location?.startsWith('https://')) {
|
|
112
|
+
return {
|
|
113
|
+
id: types_js_1.SecurityCheckIds.HTTPS_REQUIRED,
|
|
114
|
+
name: 'HTTPS Enforcement',
|
|
115
|
+
description: 'HTTP requests should redirect to HTTPS',
|
|
116
|
+
status: 'pass',
|
|
117
|
+
severity: 'critical',
|
|
118
|
+
details: 'HTTP correctly redirects to HTTPS',
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// HTTP is accessible without redirect
|
|
123
|
+
if (response.ok) {
|
|
124
|
+
return {
|
|
125
|
+
id: types_js_1.SecurityCheckIds.HTTPS_REQUIRED,
|
|
126
|
+
name: 'HTTPS Enforcement',
|
|
127
|
+
description: 'HTTP requests should redirect to HTTPS',
|
|
128
|
+
status: 'fail',
|
|
129
|
+
severity: 'critical',
|
|
130
|
+
details: 'HTTP endpoint is accessible without redirect to HTTPS',
|
|
131
|
+
recommendation: 'Configure your server to redirect all HTTP traffic to HTTPS',
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// HTTP returns error (good - means HTTPS only)
|
|
135
|
+
return {
|
|
136
|
+
id: types_js_1.SecurityCheckIds.HTTPS_REQUIRED,
|
|
137
|
+
name: 'HTTPS Enforcement',
|
|
138
|
+
description: 'HTTP requests should redirect to HTTPS',
|
|
139
|
+
status: 'pass',
|
|
140
|
+
severity: 'critical',
|
|
141
|
+
details: 'HTTP endpoint not accessible (HTTPS only)',
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// HTTP connection failed - HTTPS only
|
|
146
|
+
return {
|
|
147
|
+
id: types_js_1.SecurityCheckIds.HTTPS_REQUIRED,
|
|
148
|
+
name: 'HTTPS Enforcement',
|
|
149
|
+
description: 'HTTP requests should redirect to HTTPS',
|
|
150
|
+
status: 'pass',
|
|
151
|
+
severity: 'critical',
|
|
152
|
+
details: 'HTTP endpoint not accessible (HTTPS only)',
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Check 2: Private IP Detection
|
|
158
|
+
*/
|
|
159
|
+
async function checkPrivateIp(domain) {
|
|
160
|
+
// Check if domain looks like a private IP or localhost
|
|
161
|
+
const privatePatterns = [
|
|
162
|
+
/^localhost$/i,
|
|
163
|
+
/^127\.\d+\.\d+\.\d+$/,
|
|
164
|
+
/^10\.\d+\.\d+\.\d+$/,
|
|
165
|
+
/^172\.(1[6-9]|2\d|3[01])\.\d+\.\d+$/,
|
|
166
|
+
/^192\.168\.\d+\.\d+$/,
|
|
167
|
+
/^::1$/,
|
|
168
|
+
/^fc00:/i,
|
|
169
|
+
/^fd00:/i,
|
|
170
|
+
];
|
|
171
|
+
const isPrivate = privatePatterns.some(pattern => pattern.test(domain));
|
|
172
|
+
if (isPrivate) {
|
|
173
|
+
return {
|
|
174
|
+
id: types_js_1.SecurityCheckIds.PRIVATE_IP,
|
|
175
|
+
name: 'Private IP Detection',
|
|
176
|
+
description: 'Endpoint should not use private/internal IP addresses',
|
|
177
|
+
status: 'fail',
|
|
178
|
+
severity: 'high',
|
|
179
|
+
details: `Domain "${domain}" appears to be a private or internal address`,
|
|
180
|
+
recommendation: 'Use a public domain name for production UCP endpoints',
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
id: types_js_1.SecurityCheckIds.PRIVATE_IP,
|
|
185
|
+
name: 'Private IP Detection',
|
|
186
|
+
description: 'Endpoint should not use private/internal IP addresses',
|
|
187
|
+
status: 'pass',
|
|
188
|
+
severity: 'high',
|
|
189
|
+
details: 'Domain is publicly routable',
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Check 3: TLS Version
|
|
194
|
+
*/
|
|
195
|
+
async function checkTlsVersion(_url, _response) {
|
|
196
|
+
// Note: Browser fetch doesn't expose TLS version directly
|
|
197
|
+
// We can only verify HTTPS is working
|
|
198
|
+
return {
|
|
199
|
+
id: types_js_1.SecurityCheckIds.TLS_VERSION,
|
|
200
|
+
name: 'TLS Configuration',
|
|
201
|
+
description: 'Endpoint should use TLS 1.2 or higher',
|
|
202
|
+
status: 'pass',
|
|
203
|
+
severity: 'high',
|
|
204
|
+
details: 'HTTPS connection successful (TLS version not directly verifiable from browser)',
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Check 4: CORS Configuration
|
|
209
|
+
*/
|
|
210
|
+
async function checkCorsConfiguration(_response, headers) {
|
|
211
|
+
const acao = headers.get('access-control-allow-origin');
|
|
212
|
+
const acam = headers.get('access-control-allow-methods');
|
|
213
|
+
const acah = headers.get('access-control-allow-headers');
|
|
214
|
+
if (!acao) {
|
|
215
|
+
return {
|
|
216
|
+
id: types_js_1.SecurityCheckIds.CORS_CONFIG,
|
|
217
|
+
name: 'CORS Configuration',
|
|
218
|
+
description: 'CORS should be properly configured for AI agent access',
|
|
219
|
+
status: 'warn',
|
|
220
|
+
severity: 'medium',
|
|
221
|
+
details: 'No Access-Control-Allow-Origin header found',
|
|
222
|
+
recommendation: 'Configure CORS headers to allow AI agents to access your UCP endpoint',
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
// Check if CORS is too permissive
|
|
226
|
+
if (acao === '*') {
|
|
227
|
+
return {
|
|
228
|
+
id: types_js_1.SecurityCheckIds.CORS_CONFIG,
|
|
229
|
+
name: 'CORS Configuration',
|
|
230
|
+
description: 'CORS should be properly configured for AI agent access',
|
|
231
|
+
status: 'warn',
|
|
232
|
+
severity: 'low',
|
|
233
|
+
details: 'CORS allows all origins (*). Consider restricting to known AI agent domains.',
|
|
234
|
+
recommendation: 'For production, consider restricting CORS to specific trusted origins',
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
const hasGoodConfig = acao && (acam || acah);
|
|
238
|
+
return {
|
|
239
|
+
id: types_js_1.SecurityCheckIds.CORS_CONFIG,
|
|
240
|
+
name: 'CORS Configuration',
|
|
241
|
+
description: 'CORS should be properly configured for AI agent access',
|
|
242
|
+
status: hasGoodConfig ? 'pass' : 'warn',
|
|
243
|
+
severity: 'medium',
|
|
244
|
+
details: `CORS configured: Origin=${acao}${acam ? `, Methods=${acam}` : ''}`,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Check 5: Security Headers
|
|
249
|
+
*/
|
|
250
|
+
async function checkSecurityHeaders(headers) {
|
|
251
|
+
const securityHeaders = {
|
|
252
|
+
'x-content-type-options': headers.get('x-content-type-options'),
|
|
253
|
+
'x-frame-options': headers.get('x-frame-options'),
|
|
254
|
+
'x-xss-protection': headers.get('x-xss-protection'),
|
|
255
|
+
'strict-transport-security': headers.get('strict-transport-security'),
|
|
256
|
+
'content-security-policy': headers.get('content-security-policy'),
|
|
257
|
+
};
|
|
258
|
+
const presentHeaders = [];
|
|
259
|
+
const missingHeaders = [];
|
|
260
|
+
// Check important headers
|
|
261
|
+
if (securityHeaders['strict-transport-security']) {
|
|
262
|
+
presentHeaders.push('HSTS');
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
missingHeaders.push('HSTS');
|
|
266
|
+
}
|
|
267
|
+
if (securityHeaders['x-content-type-options']) {
|
|
268
|
+
presentHeaders.push('X-Content-Type-Options');
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
missingHeaders.push('X-Content-Type-Options');
|
|
272
|
+
}
|
|
273
|
+
if (securityHeaders['x-frame-options']) {
|
|
274
|
+
presentHeaders.push('X-Frame-Options');
|
|
275
|
+
}
|
|
276
|
+
// Calculate status based on critical headers
|
|
277
|
+
const hasHsts = !!securityHeaders['strict-transport-security'];
|
|
278
|
+
const hasXcto = !!securityHeaders['x-content-type-options'];
|
|
279
|
+
let status = 'pass';
|
|
280
|
+
let severity = 'medium';
|
|
281
|
+
if (!hasHsts && !hasXcto) {
|
|
282
|
+
status = 'fail';
|
|
283
|
+
severity = 'medium';
|
|
284
|
+
}
|
|
285
|
+
else if (!hasHsts || !hasXcto) {
|
|
286
|
+
status = 'warn';
|
|
287
|
+
severity = 'low';
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
id: types_js_1.SecurityCheckIds.SECURITY_HEADERS,
|
|
291
|
+
name: 'Security Headers',
|
|
292
|
+
description: 'Response should include security headers (HSTS, X-Content-Type-Options)',
|
|
293
|
+
status,
|
|
294
|
+
severity,
|
|
295
|
+
details: presentHeaders.length > 0
|
|
296
|
+
? `Present: ${presentHeaders.join(', ')}${missingHeaders.length > 0 ? `. Missing: ${missingHeaders.join(', ')}` : ''}`
|
|
297
|
+
: 'No security headers found',
|
|
298
|
+
recommendation: missingHeaders.length > 0
|
|
299
|
+
? `Add missing security headers: ${missingHeaders.join(', ')}`
|
|
300
|
+
: undefined,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Check 6: Content-Type
|
|
305
|
+
*/
|
|
306
|
+
async function checkContentType(headers) {
|
|
307
|
+
const contentType = headers.get('content-type');
|
|
308
|
+
if (!contentType) {
|
|
309
|
+
return {
|
|
310
|
+
id: types_js_1.SecurityCheckIds.CONTENT_TYPE,
|
|
311
|
+
name: 'Content-Type Header',
|
|
312
|
+
description: 'Response should have correct Content-Type for JSON',
|
|
313
|
+
status: 'warn',
|
|
314
|
+
severity: 'low',
|
|
315
|
+
details: 'No Content-Type header found',
|
|
316
|
+
recommendation: 'Set Content-Type: application/json for UCP endpoints',
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
const isJson = contentType.includes('application/json');
|
|
320
|
+
return {
|
|
321
|
+
id: types_js_1.SecurityCheckIds.CONTENT_TYPE,
|
|
322
|
+
name: 'Content-Type Header',
|
|
323
|
+
description: 'Response should have correct Content-Type for JSON',
|
|
324
|
+
status: isJson ? 'pass' : 'warn',
|
|
325
|
+
severity: 'low',
|
|
326
|
+
details: `Content-Type: ${contentType}`,
|
|
327
|
+
recommendation: isJson ? undefined : 'Set Content-Type: application/json for UCP endpoints',
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Check 7: Rate Limiting
|
|
332
|
+
*/
|
|
333
|
+
async function checkRateLimiting(headers) {
|
|
334
|
+
// Look for common rate limiting headers
|
|
335
|
+
const rateLimitHeaders = {
|
|
336
|
+
'x-ratelimit-limit': headers.get('x-ratelimit-limit'),
|
|
337
|
+
'x-ratelimit-remaining': headers.get('x-ratelimit-remaining'),
|
|
338
|
+
'x-rate-limit-limit': headers.get('x-rate-limit-limit'),
|
|
339
|
+
'ratelimit-limit': headers.get('ratelimit-limit'),
|
|
340
|
+
'retry-after': headers.get('retry-after'),
|
|
341
|
+
};
|
|
342
|
+
const hasRateLimiting = Object.values(rateLimitHeaders).some(v => v !== null);
|
|
343
|
+
if (hasRateLimiting) {
|
|
344
|
+
const limitValue = rateLimitHeaders['x-ratelimit-limit'] ||
|
|
345
|
+
rateLimitHeaders['x-rate-limit-limit'] ||
|
|
346
|
+
rateLimitHeaders['ratelimit-limit'];
|
|
347
|
+
return {
|
|
348
|
+
id: types_js_1.SecurityCheckIds.RATE_LIMITING,
|
|
349
|
+
name: 'Rate Limiting',
|
|
350
|
+
description: 'Endpoint should have rate limiting to prevent abuse',
|
|
351
|
+
status: 'pass',
|
|
352
|
+
severity: 'high',
|
|
353
|
+
details: `Rate limiting detected${limitValue ? `: ${limitValue} requests` : ''}`,
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
id: types_js_1.SecurityCheckIds.RATE_LIMITING,
|
|
358
|
+
name: 'Rate Limiting',
|
|
359
|
+
description: 'Endpoint should have rate limiting to prevent abuse',
|
|
360
|
+
status: 'warn',
|
|
361
|
+
severity: 'high',
|
|
362
|
+
details: 'No rate limiting headers detected (may still be present server-side)',
|
|
363
|
+
recommendation: 'Implement rate limiting to protect against abuse and DoS attacks',
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Check 8: Cache Headers
|
|
368
|
+
*/
|
|
369
|
+
async function checkCacheHeaders(headers) {
|
|
370
|
+
const cacheControl = headers.get('cache-control');
|
|
371
|
+
const etag = headers.get('etag');
|
|
372
|
+
const lastModified = headers.get('last-modified');
|
|
373
|
+
const hasCaching = cacheControl || etag || lastModified;
|
|
374
|
+
if (!hasCaching) {
|
|
375
|
+
return {
|
|
376
|
+
id: types_js_1.SecurityCheckIds.CACHE_HEADERS,
|
|
377
|
+
name: 'Cache Headers',
|
|
378
|
+
description: 'Response should have appropriate caching headers',
|
|
379
|
+
status: 'pass',
|
|
380
|
+
severity: 'info',
|
|
381
|
+
details: 'No caching headers found (optional)',
|
|
382
|
+
recommendation: 'Consider adding Cache-Control headers for better performance',
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
const details = [];
|
|
386
|
+
if (cacheControl)
|
|
387
|
+
details.push(`Cache-Control: ${cacheControl}`);
|
|
388
|
+
if (etag)
|
|
389
|
+
details.push('ETag present');
|
|
390
|
+
if (lastModified)
|
|
391
|
+
details.push('Last-Modified present');
|
|
392
|
+
return {
|
|
393
|
+
id: types_js_1.SecurityCheckIds.CACHE_HEADERS,
|
|
394
|
+
name: 'Cache Headers',
|
|
395
|
+
description: 'Response should have appropriate caching headers',
|
|
396
|
+
status: 'pass',
|
|
397
|
+
severity: 'info',
|
|
398
|
+
details: details.join(', '),
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Check 9: Error Disclosure
|
|
403
|
+
*/
|
|
404
|
+
async function checkErrorDisclosure(body) {
|
|
405
|
+
// Look for signs of stack traces or internal error details
|
|
406
|
+
const sensitivePatterns = [
|
|
407
|
+
/stack\s*trace/i,
|
|
408
|
+
/at\s+\w+\s+\([^)]+:\d+:\d+\)/, // Stack trace lines
|
|
409
|
+
/exception|error.*at\s+line/i,
|
|
410
|
+
/mysql|postgresql|mongodb|redis/i, // Database names in errors
|
|
411
|
+
/\/home\/|\/var\/|\/usr\/|C:\\|D:\\/i, // File paths
|
|
412
|
+
/password|secret|api[_-]?key/i,
|
|
413
|
+
];
|
|
414
|
+
const foundPatterns = [];
|
|
415
|
+
for (const pattern of sensitivePatterns) {
|
|
416
|
+
if (pattern.test(body)) {
|
|
417
|
+
const match = body.match(pattern);
|
|
418
|
+
if (match) {
|
|
419
|
+
foundPatterns.push(match[0].substring(0, 30));
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (foundPatterns.length > 0) {
|
|
424
|
+
return {
|
|
425
|
+
id: types_js_1.SecurityCheckIds.ERROR_DISCLOSURE,
|
|
426
|
+
name: 'Error Information Disclosure',
|
|
427
|
+
description: 'Response should not expose internal error details or stack traces',
|
|
428
|
+
status: 'warn',
|
|
429
|
+
severity: 'medium',
|
|
430
|
+
details: `Potentially sensitive information found: ${foundPatterns.join(', ')}`,
|
|
431
|
+
recommendation: 'Ensure production responses do not expose stack traces or internal paths',
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
return {
|
|
435
|
+
id: types_js_1.SecurityCheckIds.ERROR_DISCLOSURE,
|
|
436
|
+
name: 'Error Information Disclosure',
|
|
437
|
+
description: 'Response should not expose internal error details or stack traces',
|
|
438
|
+
status: 'pass',
|
|
439
|
+
severity: 'medium',
|
|
440
|
+
details: 'No sensitive error information detected',
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Check 10: Response Time
|
|
445
|
+
*/
|
|
446
|
+
function checkResponseTime(responseTimeMs) {
|
|
447
|
+
if (!responseTimeMs) {
|
|
448
|
+
return createSkippedCheck(types_js_1.SecurityCheckIds.RESPONSE_TIME, 'Response Time', 'Could not measure response time');
|
|
449
|
+
}
|
|
450
|
+
let status = 'pass';
|
|
451
|
+
let severity = 'low';
|
|
452
|
+
let recommendation;
|
|
453
|
+
if (responseTimeMs > 5000) {
|
|
454
|
+
status = 'fail';
|
|
455
|
+
severity = 'medium';
|
|
456
|
+
recommendation = 'Response time is very slow. Consider optimizing your endpoint or using a CDN.';
|
|
457
|
+
}
|
|
458
|
+
else if (responseTimeMs > 2000) {
|
|
459
|
+
status = 'warn';
|
|
460
|
+
severity = 'low';
|
|
461
|
+
recommendation = 'Response time is slow. Consider optimizing or using caching.';
|
|
462
|
+
}
|
|
463
|
+
return {
|
|
464
|
+
id: types_js_1.SecurityCheckIds.RESPONSE_TIME,
|
|
465
|
+
name: 'Response Time',
|
|
466
|
+
description: 'Endpoint should respond quickly to prevent timeouts',
|
|
467
|
+
status,
|
|
468
|
+
severity,
|
|
469
|
+
details: `Response time: ${responseTimeMs}ms`,
|
|
470
|
+
recommendation,
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Create a skipped check result
|
|
475
|
+
*/
|
|
476
|
+
function createSkippedCheck(id, name, reason) {
|
|
477
|
+
return {
|
|
478
|
+
id,
|
|
479
|
+
name,
|
|
480
|
+
description: reason,
|
|
481
|
+
status: 'skip',
|
|
482
|
+
severity: 'info',
|
|
483
|
+
details: `Skipped: ${reason}`,
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Calculate summary from checks
|
|
488
|
+
*/
|
|
489
|
+
function calculateSummary(checks) {
|
|
490
|
+
return {
|
|
491
|
+
passed: checks.filter(c => c.status === 'pass').length,
|
|
492
|
+
failed: checks.filter(c => c.status === 'fail').length,
|
|
493
|
+
warnings: checks.filter(c => c.status === 'warn').length,
|
|
494
|
+
skipped: checks.filter(c => c.status === 'skip').length,
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Calculate security score (0-100)
|
|
499
|
+
*/
|
|
500
|
+
function calculateScore(checks) {
|
|
501
|
+
const weights = {
|
|
502
|
+
critical: 25,
|
|
503
|
+
high: 20,
|
|
504
|
+
medium: 15,
|
|
505
|
+
low: 10,
|
|
506
|
+
info: 5,
|
|
507
|
+
};
|
|
508
|
+
let totalWeight = 0;
|
|
509
|
+
let earnedPoints = 0;
|
|
510
|
+
for (const check of checks) {
|
|
511
|
+
if (check.status === 'skip')
|
|
512
|
+
continue;
|
|
513
|
+
const weight = weights[check.severity];
|
|
514
|
+
totalWeight += weight;
|
|
515
|
+
if (check.status === 'pass') {
|
|
516
|
+
earnedPoints += weight;
|
|
517
|
+
}
|
|
518
|
+
else if (check.status === 'warn') {
|
|
519
|
+
earnedPoints += weight * 0.5;
|
|
520
|
+
}
|
|
521
|
+
// 'fail' gets 0 points
|
|
522
|
+
}
|
|
523
|
+
if (totalWeight === 0)
|
|
524
|
+
return 0;
|
|
525
|
+
return Math.round((earnedPoints / totalWeight) * 100);
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Calculate grade from score
|
|
529
|
+
*/
|
|
530
|
+
function calculateGrade(score) {
|
|
531
|
+
if (score >= 90)
|
|
532
|
+
return 'A';
|
|
533
|
+
if (score >= 80)
|
|
534
|
+
return 'B';
|
|
535
|
+
if (score >= 70)
|
|
536
|
+
return 'C';
|
|
537
|
+
if (score >= 60)
|
|
538
|
+
return 'D';
|
|
539
|
+
return 'F';
|
|
540
|
+
}
|
|
541
|
+
//# sourceMappingURL=security-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-scanner.js","sourceRoot":"","sources":["../../src/security/security-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security Scanner Types
|
|
3
|
+
* Types for UCP endpoint security posture scanning
|
|
4
|
+
*/
|
|
5
|
+
export type SecuritySeverity = 'critical' | 'high' | 'medium' | 'low' | 'info';
|
|
6
|
+
export type SecurityCheckStatus = 'pass' | 'fail' | 'warn' | 'skip';
|
|
7
|
+
export interface SecurityCheck {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
status: SecurityCheckStatus;
|
|
12
|
+
severity: SecuritySeverity;
|
|
13
|
+
details?: string;
|
|
14
|
+
recommendation?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface SecurityScanResult {
|
|
17
|
+
domain: string;
|
|
18
|
+
endpoint: string;
|
|
19
|
+
scanned_at: string;
|
|
20
|
+
score: number;
|
|
21
|
+
grade: string;
|
|
22
|
+
checks: SecurityCheck[];
|
|
23
|
+
summary: {
|
|
24
|
+
passed: number;
|
|
25
|
+
failed: number;
|
|
26
|
+
warnings: number;
|
|
27
|
+
skipped: number;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export interface SecurityScanOptions {
|
|
31
|
+
timeoutMs?: number;
|
|
32
|
+
skipTlsCheck?: boolean;
|
|
33
|
+
includeHeaders?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export declare const SecurityCheckIds: {
|
|
36
|
+
readonly HTTPS_REQUIRED: "HTTPS_REQUIRED";
|
|
37
|
+
readonly TLS_VERSION: "TLS_VERSION";
|
|
38
|
+
readonly CORS_CONFIG: "CORS_CONFIG";
|
|
39
|
+
readonly RATE_LIMITING: "RATE_LIMITING";
|
|
40
|
+
readonly SECURITY_HEADERS: "SECURITY_HEADERS";
|
|
41
|
+
readonly CONTENT_TYPE: "CONTENT_TYPE";
|
|
42
|
+
readonly ERROR_DISCLOSURE: "ERROR_DISCLOSURE";
|
|
43
|
+
readonly PRIVATE_IP: "PRIVATE_IP";
|
|
44
|
+
readonly RESPONSE_TIME: "RESPONSE_TIME";
|
|
45
|
+
readonly CACHE_HEADERS: "CACHE_HEADERS";
|
|
46
|
+
};
|
|
47
|
+
export type SecurityCheckId = typeof SecurityCheckIds[keyof typeof SecurityCheckIds];
|
|
48
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/security/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAE/E,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAGD,eAAO,MAAM,gBAAgB;;;;;;;;;;;CAWnB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,OAAO,gBAAgB,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Security Scanner Types
|
|
4
|
+
* Types for UCP endpoint security posture scanning
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.SecurityCheckIds = void 0;
|
|
8
|
+
// Security check IDs
|
|
9
|
+
exports.SecurityCheckIds = {
|
|
10
|
+
HTTPS_REQUIRED: 'HTTPS_REQUIRED',
|
|
11
|
+
TLS_VERSION: 'TLS_VERSION',
|
|
12
|
+
CORS_CONFIG: 'CORS_CONFIG',
|
|
13
|
+
RATE_LIMITING: 'RATE_LIMITING',
|
|
14
|
+
SECURITY_HEADERS: 'SECURITY_HEADERS',
|
|
15
|
+
CONTENT_TYPE: 'CONTENT_TYPE',
|
|
16
|
+
ERROR_DISCLOSURE: 'ERROR_DISCLOSURE',
|
|
17
|
+
PRIVATE_IP: 'PRIVATE_IP',
|
|
18
|
+
RESPONSE_TIME: 'RESPONSE_TIME',
|
|
19
|
+
CACHE_HEADERS: 'CACHE_HEADERS',
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/security/types.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAqCH,qBAAqB;AACR,QAAA,gBAAgB,GAAG;IAC9B,cAAc,EAAE,gBAAgB;IAChC,WAAW,EAAE,aAAa;IAC1B,WAAW,EAAE,aAAa;IAC1B,aAAa,EAAE,eAAe;IAC9B,gBAAgB,EAAE,kBAAkB;IACpC,YAAY,EAAE,cAAc;IAC5B,gBAAgB,EAAE,kBAAkB;IACpC,UAAU,EAAE,YAAY;IACxB,aAAa,EAAE,eAAe;IAC9B,aAAa,EAAE,eAAe;CACtB,CAAC"}
|