@slicedearth/whoisleuth-cli 1.43.0 → 1.47.4
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/DISCLOSURE +7 -3
- package/NOTICE +5 -4
- package/README.md +67 -10
- package/bin/whoisleuth.mjs +22 -9
- package/cli/arguments.mjs +256 -9
- package/cli/artifact-structure.mjs +1833 -0
- package/cli/artifact-verify.mjs +242 -49
- package/cli/bounded-json.mjs +1 -0
- package/cli/bulk-checkpoint.mjs +67 -31
- package/cli/bulk-command-runner.mjs +16 -6
- package/cli/bulk.mjs +18 -7
- package/cli/case-pack.mjs +819 -34
- package/cli/command-reference.mjs +48 -24
- package/cli/completion.mjs +50 -11
- package/cli/config-profile.mjs +15 -12
- package/cli/ct-event-intake.mjs +32 -2
- package/cli/discovery-observation-snapshot.mjs +8 -14
- package/cli/discovery-scan-command-runner.mjs +18 -6
- package/cli/discovery-snapshot.mjs +8 -15
- package/cli/discovery-workflow.mjs +2 -3
- package/cli/doctor.mjs +2 -2
- package/cli/domain-control-monitor.mjs +21 -15
- package/cli/domain-control-observations.mjs +25 -2
- package/cli/errors.mjs +7 -1
- package/cli/evidence-command-runner.mjs +17 -11
- package/cli/evidence-signing.mjs +73 -45
- package/cli/export-evidence.mjs +11 -4
- package/cli/formatters/html.mjs +3 -3
- package/cli/formatters/json.mjs +12 -4
- package/cli/formatters/terminal.mjs +4 -1
- package/cli/http.mjs +2 -1
- package/cli/input.mjs +57 -0
- package/cli/interchange-report.mjs +226 -0
- package/cli/investigation-manifest.mjs +16 -17
- package/cli/investigation-run.mjs +71 -23
- package/cli/local-mmdb-review.mjs +45 -14
- package/cli/lookup-command-runner.mjs +2 -2
- package/cli/lookup-diff.mjs +9 -0
- package/cli/lookup-reconcile.mjs +1 -1
- package/cli/mail-review.mjs +5 -5
- package/cli/manual.mjs +1 -1
- package/cli/network-command-runner.mjs +78 -0
- package/cli/offline-evidence-review.mjs +28 -8
- package/cli/page-compare.mjs +8 -5
- package/cli/registry-cohort.mjs +385 -61
- package/cli/registry-fixture-scaffold.mjs +4 -3
- package/cli/registry-support.mjs +2 -1
- package/cli/retained-artifact-diff.mjs +376 -0
- package/cli/risk-calibration.mjs +7 -5
- package/cli/runner.mjs +150 -177
- package/cli/saved-lookup.mjs +26 -3
- package/cli/sharing-review.mjs +12 -6
- package/docs/cli-reference.md +467 -74
- package/docs/cli.md +25 -5
- package/frontend/src/lib/analysis/acquisition-decision-packet.js +4 -4
- package/frontend/src/lib/analysis/acquisition-due-diligence.js +1 -1
- package/frontend/src/lib/analysis/artifact-integrity.js +42 -0
- package/frontend/src/lib/analysis/brand-profile-model.js +33 -7
- package/frontend/src/lib/analysis/bulk-domain-comparison.js +25 -5
- package/frontend/src/lib/analysis/bulk-mail-exposure.js +66 -15
- package/frontend/src/lib/analysis/bulk-retry-plan.js +1 -1
- package/frontend/src/lib/analysis/bulk-review-export.js +7 -6
- package/frontend/src/lib/analysis/bulk-review-model.js +3 -2
- package/frontend/src/lib/analysis/bulk-session-model.js +192 -26
- package/frontend/src/lib/analysis/bulk-sort.js +4 -0
- package/frontend/src/lib/analysis/case-brand-profile-references.js +85 -0
- package/frontend/src/lib/analysis/case-evidence-model.js +9 -1
- package/frontend/src/lib/analysis/case-investigation-branch-model.js +134 -0
- package/frontend/src/lib/analysis/case-migration-model.js +83 -31
- package/frontend/src/lib/analysis/case-record-contracts.js +4 -2
- package/frontend/src/lib/analysis/case-record-core.js +1 -1
- package/frontend/src/lib/analysis/case-record-model.js +2 -0
- package/frontend/src/lib/analysis/case-record-operations.js +43 -13
- package/frontend/src/lib/analysis/case-report.js +39 -6
- package/frontend/src/lib/analysis/case-response-model.js +66 -7
- package/frontend/src/lib/analysis/case-response-packet.js +15 -5
- package/frontend/src/lib/analysis/comparison-ledger-bulk.js +366 -0
- package/frontend/src/lib/analysis/comparison-ledger-contract.js +241 -0
- package/frontend/src/lib/analysis/comparison-ledger-json.js +79 -0
- package/frontend/src/lib/analysis/comparison-ledger-serialization.js +51 -0
- package/frontend/src/lib/analysis/domain-control-manifest-core.js +145 -0
- package/frontend/src/lib/analysis/domain-control-records.js +88 -0
- package/frontend/src/lib/analysis/external-findings-import.js +70 -6
- package/frontend/src/lib/analysis/investigation-capsule.js +47 -13
- package/frontend/src/lib/analysis/investigation-guide.js +52 -10
- package/frontend/src/lib/analysis/investigation-template-model.js +9 -6
- package/frontend/src/lib/analysis/lookup-asset-graph.js +8 -8
- package/frontend/src/lib/analysis/lookup-claim-passport.js +236 -0
- package/frontend/src/lib/analysis/lookup-claim-readiness.js +280 -0
- package/frontend/src/lib/analysis/lookup-decision-support.js +63 -8
- package/frontend/src/lib/analysis/lookup-presentation.js +70 -14
- package/frontend/src/lib/analysis/lookup-source-refresh.js +36 -63
- package/frontend/src/lib/analysis/opaque-reference-id.js +9 -0
- package/frontend/src/lib/analysis/utils.js +27 -4
- package/frontend/src/lib/analysis/visualization-matrix.js +71 -28
- package/frontend/src/lib/analysis/visualization-models.js +63 -94
- package/frontend/src/lib/analysis/visualization-time-series.js +53 -12
- package/frontend/src/lib/analysis/website-snapshot-model.js +6 -0
- package/frontend/src/lib/analysis/workspace-archive-crypto.js +1 -4
- package/frontend/src/lib/analysis/workspace-archive.js +105 -19
- package/lib/application-version.mjs +3 -0
- package/lib/availability.mjs +14 -12
- package/lib/bounded-file.mjs +82 -0
- package/lib/bounded-json-response.mjs +170 -0
- package/lib/bounded-json.mjs +249 -0
- package/lib/browser-library-profile.mjs +167 -38
- package/lib/certificate-extension-profile.mjs +2 -1
- package/lib/cryptographic-assurance.mjs +155 -0
- package/lib/ct-search.mjs +87 -47
- package/lib/dns-intelligence.mjs +3 -2
- package/lib/dns-resolver-selection.mjs +6 -4
- package/lib/dnssec-chain-validation.mjs +1053 -0
- package/lib/dnssec-evidence-validation.mjs +10 -3
- package/lib/domain-change-packet.mjs +7 -5
- package/lib/domain-control-manifest.mjs +17 -129
- package/lib/domain-posture.mjs +7 -4
- package/lib/evidence-export.mjs +751 -78
- package/lib/evidence-report-markdown.mjs +3 -0
- package/lib/evidence-report.mjs +5 -0
- package/lib/favicon.mjs +8 -5
- package/lib/http-evidence-bounds.mjs +3 -0
- package/lib/http-intelligence.mjs +2 -5
- package/lib/interchange-fidelity-registry.mjs +122 -0
- package/lib/local-geoip-evidence.mjs +2 -1
- package/lib/lookup-cache.mjs +5 -1
- package/lib/lookup-network-evidence-bounds.mjs +9 -0
- package/lib/lookup-response-contract.mjs +691 -3
- package/lib/lookup.mjs +2 -2
- package/lib/observation.mjs +7 -6
- package/lib/outbound-identity.mjs +2 -3
- package/lib/perceptual-hash.mjs +12 -4
- package/lib/portable-generator.mjs +21 -0
- package/lib/provider-policy-admission.mjs +9 -4
- package/lib/rdap-normalization.mjs +18 -5
- package/lib/rdap-registrar.mjs +5 -1
- package/lib/rdap-transport.mjs +6 -6
- package/lib/registry-capabilities.mjs +3 -0
- package/lib/registry-capability-catalogue.mjs +12 -2
- package/lib/registry-comparison.mjs +28 -11
- package/lib/risk-calibration-summary.mjs +338 -0
- package/lib/rpki-evidence.mjs +9 -8
- package/lib/safe-fetch.mjs +96 -42
- package/lib/security-txt.mjs +26 -3
- package/lib/service-binding-dns.mjs +6 -1
- package/lib/smtp-transport-review.mjs +784 -0
- package/lib/sslbl-certificates.generated.mjs +136 -134
- package/lib/threat-intelligence-runtime.mjs +4 -13
- package/lib/threat-intelligence-types.mjs +18 -1
- package/lib/tls-intelligence.mjs +11 -5
- package/lib/tlsa-evidence.mjs +37 -7
- package/lib/website-technology.mjs +2 -6
- package/package.json +1 -1
- package/third-party-notices.txt +95 -5817
package/lib/security-txt.mjs
CHANGED
|
@@ -61,6 +61,23 @@ function normalizedPublishedUri(value, schemes) {
|
|
|
61
61
|
function normalizedHttpsUrl(value) {
|
|
62
62
|
return normalizedPublishedUri(value, HTTPS_PROTOCOLS);
|
|
63
63
|
}
|
|
64
|
+
function normalizedCanonicalComparisonUrl(value) {
|
|
65
|
+
if (!value || value.length > MAX_SECURITY_TXT_URL_LENGTH || URI_CONTROL_CHARACTER_RE.test(value))
|
|
66
|
+
return null;
|
|
67
|
+
try {
|
|
68
|
+
const url = new URL(value.trim());
|
|
69
|
+
if (url.protocol !== 'https:' || !url.hostname || url.username || url.password)
|
|
70
|
+
return null;
|
|
71
|
+
// A fragment is never part of the retrieval URI. Preserve the query only
|
|
72
|
+
// for the transient RFC 9116 Canonical comparison; retained values remain
|
|
73
|
+
// query-free under the existing privacy-minimised output contract.
|
|
74
|
+
url.hash = '';
|
|
75
|
+
return url.toString().slice(0, MAX_SECURITY_TXT_URL_LENGTH);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
64
81
|
function eligibleHttpsFetchUrl(value) {
|
|
65
82
|
if (!value || value.length > MAX_SECURITY_TXT_URL_LENGTH || URI_CONTROL_CHARACTER_RE.test(value))
|
|
66
83
|
return null;
|
|
@@ -113,6 +130,7 @@ function parseSecurityTxt(text, options = {}) {
|
|
|
113
130
|
const policies = [];
|
|
114
131
|
const encryption = [];
|
|
115
132
|
const canonical = [];
|
|
133
|
+
const canonicalComparison = [];
|
|
116
134
|
const preferredLanguages = [];
|
|
117
135
|
const expires = [];
|
|
118
136
|
for (const rawLine of lines.slice(0, MAX_SECURITY_TXT_LINES)) {
|
|
@@ -157,8 +175,11 @@ function parseSecurityTxt(text, options = {}) {
|
|
|
157
175
|
}
|
|
158
176
|
else if (field === 'canonical') {
|
|
159
177
|
normalized = normalizedHttpsUrl(value);
|
|
160
|
-
|
|
178
|
+
const comparisonValue = normalizedCanonicalComparisonUrl(value);
|
|
179
|
+
if (normalized && comparisonValue) {
|
|
161
180
|
canonical.push(normalized);
|
|
181
|
+
canonicalComparison.push(comparisonValue);
|
|
182
|
+
}
|
|
162
183
|
else
|
|
163
184
|
malformedCount += 1;
|
|
164
185
|
}
|
|
@@ -187,8 +208,10 @@ function parseSecurityTxt(text, options = {}) {
|
|
|
187
208
|
.some((entry) => entry.truncated);
|
|
188
209
|
const expiresAt = expires.length === 1 ? expires[0] : null;
|
|
189
210
|
const finalUrl = options.finalUrl ? normalizedHttpsUrl(options.finalUrl) : null;
|
|
190
|
-
const
|
|
191
|
-
|
|
211
|
+
const finalComparisonUrl = options.finalUrl ? normalizedCanonicalComparisonUrl(options.finalUrl) : null;
|
|
212
|
+
const canonicalMatches = boundedCanonical.values.length && finalUrl && finalComparisonUrl
|
|
213
|
+
? canonicalComparison.slice(0, MAX_SECURITY_TXT_VALUES)
|
|
214
|
+
.some((value) => value.toLowerCase() === finalComparisonUrl.toLowerCase())
|
|
192
215
|
: null;
|
|
193
216
|
const stale = Boolean(expiresAt && Date.parse(expiresAt) <= (options.now ?? Date.now()));
|
|
194
217
|
const requiredMalformed = boundedContacts.values.length === 0 || expires.length !== 1;
|
|
@@ -450,16 +450,21 @@ function defaultTcpExchange(query, resolver, options) {
|
|
|
450
450
|
const chunks = [];
|
|
451
451
|
let totalLength = 0;
|
|
452
452
|
let settled = false;
|
|
453
|
+
let hardDeadline = null;
|
|
453
454
|
const finish = (error, response) => {
|
|
454
455
|
if (settled)
|
|
455
456
|
return;
|
|
456
457
|
settled = true;
|
|
458
|
+
if (hardDeadline)
|
|
459
|
+
clearTimeout(hardDeadline);
|
|
457
460
|
socket.destroy();
|
|
458
461
|
if (error)
|
|
459
462
|
reject(error);
|
|
460
463
|
else
|
|
461
464
|
resolve(response);
|
|
462
465
|
};
|
|
466
|
+
hardDeadline = setTimeout(() => finish(new ServiceBindingDnsError('DNS TCP query timed out', 'ETIMEOUT')), options.timeoutMs);
|
|
467
|
+
hardDeadline.unref();
|
|
463
468
|
socket.setTimeout(options.timeoutMs, () => finish(new ServiceBindingDnsError('DNS TCP query timed out', 'ETIMEOUT')));
|
|
464
469
|
socket.once('error', (error) => finish(error));
|
|
465
470
|
socket.on('data', (chunk) => {
|
|
@@ -605,4 +610,4 @@ async function resolveServiceBindingRecords(nameValue, type, options = {}) {
|
|
|
605
610
|
.slice(0, MAX_ERROR_LENGTH);
|
|
606
611
|
throw new ServiceBindingDnsError(detail || 'DNS query failed', 'EDNSFAIL');
|
|
607
612
|
}
|
|
608
|
-
export { DNS_TIMEOUT_MS as SERVICE_BINDING_DNS_TIMEOUT_MS, HTTPS_TYPE, MAX_SERVICE_BINDING_RECORDS, SVCB_TYPE, ServiceBindingDnsError, buildServiceBindingDnsQuery, formatIpv6, parseResolverEndpoint, parseServiceBindingDnsResponse, resolveServiceBindingRecords, };
|
|
613
|
+
export { DNS_TIMEOUT_MS as SERVICE_BINDING_DNS_TIMEOUT_MS, HTTPS_TYPE, MAX_DNS_MESSAGE_BYTES, MAX_SERVICE_BINDING_RECORDS, SVCB_TYPE, ServiceBindingDnsError, buildServiceBindingDnsQuery, defaultTcpExchange, formatIpv6, parseResolverEndpoint, parseServiceBindingDnsResponse, resolveServiceBindingRecords, };
|