@slicedearth/whoisleuth-cli 2.0.1 → 2.2.0
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/cli/arguments.mjs +21 -5
- package/cli/artifact-validation/case-response.mjs +771 -0
- package/cli/artifact-validation/investigation-capsule.mjs +426 -0
- package/cli/artifact-validation/lookup-evidence.mjs +718 -0
- package/cli/artifact-validation/signed-review.mjs +598 -0
- package/cli/artifact-validation/structure-primitives.mjs +105 -0
- package/cli/artifact-verify.mjs +1 -1
- package/cli/assurance-command-runner.mjs +324 -0
- package/cli/command-reference.mjs +1175 -843
- package/cli/completion.mjs +56 -9
- package/cli/discriminated-command-handlers.mjs +11 -0
- package/cli/doctor.mjs +2 -2
- package/cli/evidence-command-runner.mjs +41 -31
- package/cli/export-evidence.mjs +1 -1
- package/cli/fail-policy.mjs +33 -8
- package/cli/formatters/terminal-command-formats.mjs +437 -0
- package/cli/formatters/terminal-lookup.mjs +758 -0
- package/cli/formatters/terminal-metadata.mjs +58 -0
- package/cli/formatters/terminal-shared.mjs +83 -0
- package/cli/formatters/terminal.mjs +5 -1232
- package/cli/history-command-runner.mjs +132 -0
- package/cli/inline-command-families.mjs +45 -0
- package/cli/inline-command-runner.mjs +55 -0
- package/cli/investigation-plan.mjs +9 -2
- package/cli/investigation-run.mjs +114 -9
- package/cli/lookup-brief.mjs +141 -23
- package/cli/lookup-browser-view.mjs +289 -0
- package/cli/lookup-browser.mjs +3 -288
- package/cli/mail-review.mjs +2 -6
- package/cli/offline-artifact-validation.mjs +19 -0
- package/cli/review-command-runner.mjs +269 -0
- package/cli/runner.mjs +15 -972
- package/cli/saved-lookup.mjs +19 -2
- package/cli/support-command-runner.mjs +229 -0
- package/cli/workflow-command-runner.mjs +129 -0
- package/docs/cli-reference.md +16 -9
- package/docs/cli.md +16 -2
- package/lib/availability.mjs +12 -9
- package/lib/bounded-contract-normalizers.mjs +2 -9
- package/lib/browser-library-profile.mjs +1 -2
- package/lib/client-behavior-profile.mjs +1 -2
- package/lib/credential-surface-profile.mjs +1 -1
- package/lib/domain-posture-analysis.mjs +10 -1
- package/lib/domain-posture.mjs +51 -23
- package/lib/evidence-export.mjs +47 -5
- package/lib/evidence-report-markdown.mjs +4 -0
- package/lib/evidence-report.mjs +50 -0
- package/lib/generated/cisa-kev-catalog.mjs +34 -4
- package/lib/generated/registrar-standing-catalogue.mjs +367 -0
- package/lib/json-record.mjs +12 -0
- package/lib/lookup-child-profile-contract.mjs +858 -0
- package/lib/lookup-contract-primitives.mjs +98 -0
- package/lib/lookup-diagnostics.mjs +96 -0
- package/lib/lookup-network-evidence-bounds.mjs +1 -0
- package/lib/lookup-response.mjs +367 -0
- package/lib/lookup.mjs +28 -443
- package/lib/page-role-profile.mjs +1 -3
- package/lib/registrar-standing-catalogue-contract.mjs +70 -0
- package/lib/registrar-standing-contract.mjs +300 -0
- package/lib/registrar-standing.mjs +269 -0
- package/lib/registry-insights.mjs +2 -8
- package/lib/risk-scoring.mjs +26 -10
- package/lib/sslbl-certificates.generated.mjs +138 -136
- package/lib/structured-data-identity.mjs +1 -3
- package/lib/technology-evidence-role.mjs +51 -0
- package/lib/threat-intelligence-runtime.mjs +3 -3
- package/lib/threat-intelligence-types.mjs +13 -0
- package/lib/threatfox-intelligence.mjs +1 -3
- package/lib/tls-intelligence.mjs +1 -2
- package/lib/urlhaus-intelligence.mjs +1 -3
- package/lib/urlscan-intelligence.mjs +1 -3
- package/lib/website-security-posture.mjs +1 -2
- package/lib/website-technology.mjs +72 -23
- package/lib/whois-common-formats.mjs +276 -0
- package/lib/whois-dialects.mjs +534 -0
- package/lib/whois-parser-support.mjs +305 -0
- package/lib/whois-parser.mjs +135 -0
- package/lib/whois.mjs +6 -1187
- package/package.json +2 -2
- package/packages/cases/case-evidence-model.mjs +9 -0
- package/packages/cases/case-migration-model.mjs +17 -11
- package/packages/cases/case-record-operations.mjs +235 -0
- package/packages/cases/case-response-model.mjs +13 -9
- package/packages/cases/case-response-packet.mjs +297 -112
- package/packages/comparison/page-similarity.mjs +23 -0
- package/packages/contracts/case-portability.mjs +235 -61
- package/packages/contracts/cli-lookup.mjs +4 -3
- package/packages/contracts/domain-control-manifest.mjs +1 -1
- package/packages/contracts/investigation-portability.mjs +1 -1
- package/packages/contracts/risk-calibration.mjs +2 -2
- package/packages/contracts/workspace-portability.mjs +34 -6
- package/packages/interchange/external-findings-import.mjs +113 -45
- package/packages/investigation/evidence-coverage-ledger.mjs +21 -0
- package/packages/investigation/lookup-claim-readiness.mjs +2 -2
- package/packages/workspace/website-snapshot-model.mjs +79 -6
- package/third-party-notices.txt +1 -1
- package/cli/artifact-structure.mjs +0 -2507
package/lib/risk-scoring.mjs
CHANGED
|
@@ -6,11 +6,21 @@ const STATE_LABELS = Object.freeze({
|
|
|
6
6
|
expiring: 'expiring/pending delete',
|
|
7
7
|
registered: 'registered',
|
|
8
8
|
});
|
|
9
|
-
// Version
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
|
|
9
|
+
// Version 8 keeps unreviewed whole-page similarity as visible review context
|
|
10
|
+
// without assigning it Risk points. Reviewed favicon and official-asset
|
|
11
|
+
// observations remain bounded within the brand-presentation family, generic
|
|
12
|
+
// operational properties remain supporting context, and missing evidence never
|
|
13
|
+
// contributes points.
|
|
14
|
+
export const RISK_MODEL_VERSION = 8;
|
|
13
15
|
export const RISK_REVIEW_THRESHOLD = 70;
|
|
16
|
+
const CURRENT_RISK_MODEL = Object.freeze({
|
|
17
|
+
modelVersion: RISK_MODEL_VERSION,
|
|
18
|
+
includePageBaselineMatch: false,
|
|
19
|
+
});
|
|
20
|
+
const RISK_MODEL_V7 = Object.freeze({
|
|
21
|
+
modelVersion: 7,
|
|
22
|
+
includePageBaselineMatch: true,
|
|
23
|
+
});
|
|
14
24
|
const RISK_STATE_BASE = Object.freeze({
|
|
15
25
|
registered: 6,
|
|
16
26
|
for_sale: 4,
|
|
@@ -114,7 +124,7 @@ function scoreQuality(input) {
|
|
|
114
124
|
}
|
|
115
125
|
// Risk prioritizes a registered lookalike/typosquat domain for analyst review.
|
|
116
126
|
// It is a heuristic indicator, never a maliciousness or safety verdict.
|
|
117
|
-
function explainRiskScoreInternal(input, excludedFamily) {
|
|
127
|
+
function explainRiskScoreInternal(input, excludedFamily, model) {
|
|
118
128
|
const state = input.availability ?? input.state;
|
|
119
129
|
if (typeof state !== 'string' || !RISK_STATES.has(state))
|
|
120
130
|
return null;
|
|
@@ -143,8 +153,9 @@ function explainRiskScoreInternal(input, excludedFamily) {
|
|
|
143
153
|
add('brand-presentation', 'Favicon resembles an official Brand Profile site', 14);
|
|
144
154
|
if (input.reusesOfficialAssets === true)
|
|
145
155
|
add('brand-presentation', 'Official asset-host relationship observed', 6);
|
|
146
|
-
if (input.pageBaselineMatch === true)
|
|
156
|
+
if (model.includePageBaselineMatch && input.pageBaselineMatch === true) {
|
|
147
157
|
add('brand-presentation', 'Multiple independently compared page-identity components match the official baseline', 14);
|
|
158
|
+
}
|
|
148
159
|
if (typeof input.phishingLanguageMatch === 'string' && input.phishingLanguageMatch.trim()) {
|
|
149
160
|
add('credential-lure', 'Suspicious urgency language observed', 8);
|
|
150
161
|
}
|
|
@@ -193,7 +204,7 @@ function explainRiskScoreInternal(input, excludedFamily) {
|
|
|
193
204
|
'external-intelligence', 'corroboration', 'operational-support',
|
|
194
205
|
];
|
|
195
206
|
return {
|
|
196
|
-
modelVersion:
|
|
207
|
+
modelVersion: model.modelVersion,
|
|
197
208
|
score,
|
|
198
209
|
rawScore,
|
|
199
210
|
capped: score !== rawScore,
|
|
@@ -205,16 +216,16 @@ function explainRiskScoreInternal(input, excludedFamily) {
|
|
|
205
216
|
};
|
|
206
217
|
}
|
|
207
218
|
export function explainRiskScore(input) {
|
|
208
|
-
return explainRiskScoreInternal(input, null);
|
|
219
|
+
return explainRiskScoreInternal(input, null, CURRENT_RISK_MODEL);
|
|
209
220
|
}
|
|
210
221
|
export function buildRiskScoreSensitivity(input) {
|
|
211
|
-
const baseline = explainRiskScoreInternal(input, null);
|
|
222
|
+
const baseline = explainRiskScoreInternal(input, null, CURRENT_RISK_MODEL);
|
|
212
223
|
if (!baseline)
|
|
213
224
|
return null;
|
|
214
225
|
const removableFamilies = REMOVABLE_RISK_FAMILIES
|
|
215
226
|
.filter((family) => baseline.families.some((item) => item.id === family && item.contribution > 0));
|
|
216
227
|
const scenarios = removableFamilies.map((excludedFamily) => {
|
|
217
|
-
const result = explainRiskScoreInternal(input, excludedFamily);
|
|
228
|
+
const result = explainRiskScoreInternal(input, excludedFamily, CURRENT_RISK_MODEL);
|
|
218
229
|
const score = result?.score ?? baseline.score;
|
|
219
230
|
return Object.freeze({ excludedFamily, score, difference: score - baseline.score });
|
|
220
231
|
}).sort((left, right) => left.score - right.score || left.excludedFamily.localeCompare(right.excludedFamily));
|
|
@@ -240,6 +251,11 @@ export function computeRiskScore(input) {
|
|
|
240
251
|
}
|
|
241
252
|
// Retained only for deterministic offline comparison of reviewed calibration
|
|
242
253
|
// datasets. Runtime lookups always use the current model above.
|
|
254
|
+
export function explainRiskScoreV7(input) {
|
|
255
|
+
return explainRiskScoreInternal(input, null, RISK_MODEL_V7);
|
|
256
|
+
}
|
|
257
|
+
// Retained only for deterministic offline comparison of reviewed calibration
|
|
258
|
+
// datasets. Runtime lookups always use the current model above.
|
|
243
259
|
export function explainRiskScoreV6(input) {
|
|
244
260
|
const state = input.availability ?? input.state;
|
|
245
261
|
if (typeof state !== 'string' || !RISK_STATES.has(state))
|