@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/cli/saved-lookup.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Buffer } from 'node:buffer';
|
|
2
|
+
import { classifyQuery } from "../lib/classify.mjs";
|
|
3
|
+
import { scanBoundedJson } from "../lib/bounded-json.mjs";
|
|
2
4
|
import { CliUsageError } from "./arguments.mjs";
|
|
3
5
|
const MAX_SAVED_LOOKUP_INPUT_BYTES = 8 * 1024 * 1024;
|
|
4
6
|
const MAX_SAVED_LOOKUP_STRING_LENGTH = 1024;
|
|
@@ -46,9 +48,21 @@ function parseSavedLookupDocument(text, options = {}) {
|
|
|
46
48
|
if (Buffer.byteLength(text, 'utf8') > MAX_SAVED_LOOKUP_INPUT_BYTES) {
|
|
47
49
|
throw new CliUsageError(`${label} is limited to ${MAX_SAVED_LOOKUP_INPUT_BYTES} bytes.`);
|
|
48
50
|
}
|
|
51
|
+
const normalized = text.replace(/^\uFEFF/, '');
|
|
52
|
+
try {
|
|
53
|
+
scanBoundedJson(normalized);
|
|
54
|
+
}
|
|
55
|
+
catch (cause) {
|
|
56
|
+
const detail = cause instanceof Error ? cause.message : '';
|
|
57
|
+
if (detail === 'Artefact input is not valid JSON.') {
|
|
58
|
+
throw new CliUsageError(`${label} must be valid JSON.`);
|
|
59
|
+
}
|
|
60
|
+
const boundedDetail = detail.replace(/^Artefact JSON /u, '');
|
|
61
|
+
throw new CliUsageError(boundedDetail ? `${label} ${boundedDetail}` : `${label} must be valid JSON.`);
|
|
62
|
+
}
|
|
49
63
|
let parsed;
|
|
50
64
|
try {
|
|
51
|
-
parsed = JSON.parse(
|
|
65
|
+
parsed = JSON.parse(normalized);
|
|
52
66
|
}
|
|
53
67
|
catch {
|
|
54
68
|
throw new CliUsageError(`${label} must be valid JSON.`);
|
|
@@ -64,8 +78,17 @@ function parseSavedLookupDocument(text, options = {}) {
|
|
|
64
78
|
if (document.mode !== 'fast' && document.mode !== 'deep') {
|
|
65
79
|
throw new CliUsageError(`${label} has an unsupported lookup mode.`);
|
|
66
80
|
}
|
|
67
|
-
requiredBoundedString(document.query, 'query');
|
|
68
|
-
requiredBoundedString(document.registrableDomain, 'registrableDomain');
|
|
81
|
+
const query = requiredBoundedString(document.query, 'query');
|
|
82
|
+
const registrableDomain = requiredBoundedString(document.registrableDomain, 'registrableDomain');
|
|
83
|
+
try {
|
|
84
|
+
const classified = classifyQuery(query);
|
|
85
|
+
if (classified.type !== 'domain' || classified.registrableDomain !== registrableDomain.toLowerCase().replace(/\.$/u, '')) {
|
|
86
|
+
throw new Error('Saved query does not match its declared registrable domain.');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
throw new CliUsageError('query must identify the declared registrable domain.');
|
|
91
|
+
}
|
|
69
92
|
requiredBoundedString(document.generatedAt, 'generatedAt');
|
|
70
93
|
const diagnostics = objectOrNull(document.diagnostics);
|
|
71
94
|
const rdapDiagnostics = objectOrNull(diagnostics?.rdap);
|
package/cli/sharing-review.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { UnsupportedOfflineArtifactError, verifyOfflineArtifact, } from "./artifact-verify.mjs";
|
|
1
|
+
import { hasVerifiedWholeArtifactIntegrity, UnsupportedOfflineArtifactError, verifyOfflineArtifact, } from "./artifact-verify.mjs";
|
|
2
2
|
const SHARING_REVIEW_SCHEMA = 'whoisleuth.cli.sharing-review';
|
|
3
|
-
const SHARING_REVIEW_VERSION =
|
|
3
|
+
const SHARING_REVIEW_VERSION = 2;
|
|
4
4
|
const MAX_SHARING_REVIEW_BYTES = 15 * 1024 * 1024;
|
|
5
5
|
const TLP_MARKINGS = ['clear', 'green', 'amber', 'amber-strict', 'red'];
|
|
6
6
|
const RECIPIENT_SCOPES = ['public', 'community', 'organization', 'named-recipients'];
|
|
@@ -103,7 +103,11 @@ async function buildSharingReview(raw, options, generatedAt = new Date().toISOSt
|
|
|
103
103
|
let integrity = 'unsupported';
|
|
104
104
|
try {
|
|
105
105
|
const verification = await verifyOfflineArtifact(raw);
|
|
106
|
-
integrity = verification.
|
|
106
|
+
integrity = verification.state === 'verified' && hasVerifiedWholeArtifactIntegrity(verification)
|
|
107
|
+
? 'verified'
|
|
108
|
+
: verification.state === 'integrity_valid'
|
|
109
|
+
? 'projection_integrity'
|
|
110
|
+
: 'structure_only';
|
|
107
111
|
}
|
|
108
112
|
catch (error) {
|
|
109
113
|
integrity = error instanceof UnsupportedOfflineArtifactError ? 'unsupported' : 'failed';
|
|
@@ -114,9 +118,11 @@ async function buildSharingReview(raw, options, generatedAt = new Date().toISOSt
|
|
|
114
118
|
? 'The artefact passed its supported local integrity contract.'
|
|
115
119
|
: integrity === 'structure_only'
|
|
116
120
|
? 'The artefact passed its structural contract but has no verified content digest.'
|
|
117
|
-
: integrity === '
|
|
118
|
-
? '
|
|
119
|
-
:
|
|
121
|
+
: integrity === 'projection_integrity'
|
|
122
|
+
? 'The artefact passed its structural contract and projection digests, but those digests do not cover the whole file.'
|
|
123
|
+
: integrity === 'unsupported'
|
|
124
|
+
? 'This artefact schema has no supported local integrity verifier; review its producer and digest contract manually.'
|
|
125
|
+
: 'The artefact failed its supported structure or integrity contract.');
|
|
120
126
|
add('human-review', options.humanReviewed ? 'pass' : 'block', 'Human review', options.humanReviewed
|
|
121
127
|
? 'A deliberate human review was recorded for this sharing decision.'
|
|
122
128
|
: 'Complete a deliberate human review before sharing.');
|