handoffprobe 0.1.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/LICENSE +201 -0
- package/README.md +533 -0
- package/dist/attacks/index.d.ts +3 -0
- package/dist/attacks/index.d.ts.map +1 -0
- package/dist/attacks/index.js +3 -0
- package/dist/attacks/index.js.map +1 -0
- package/dist/attacks/p0/approval.d.ts +5 -0
- package/dist/attacks/p0/approval.d.ts.map +1 -0
- package/dist/attacks/p0/approval.js +121 -0
- package/dist/attacks/p0/approval.js.map +1 -0
- package/dist/attacks/p0/authorization.d.ts +6 -0
- package/dist/attacks/p0/authorization.d.ts.map +1 -0
- package/dist/attacks/p0/authorization.js +241 -0
- package/dist/attacks/p0/authorization.js.map +1 -0
- package/dist/attacks/p0/credentials.d.ts +10 -0
- package/dist/attacks/p0/credentials.d.ts.map +1 -0
- package/dist/attacks/p0/credentials.js +206 -0
- package/dist/attacks/p0/credentials.js.map +1 -0
- package/dist/attacks/p0/identity.d.ts +10 -0
- package/dist/attacks/p0/identity.d.ts.map +1 -0
- package/dist/attacks/p0/identity.js +200 -0
- package/dist/attacks/p0/identity.js.map +1 -0
- package/dist/attacks/p0/index.d.ts +9 -0
- package/dist/attacks/p0/index.d.ts.map +1 -0
- package/dist/attacks/p0/index.js +9 -0
- package/dist/attacks/p0/index.js.map +1 -0
- package/dist/attacks/p0/lifecycle.d.ts +6 -0
- package/dist/attacks/p0/lifecycle.d.ts.map +1 -0
- package/dist/attacks/p0/lifecycle.js +142 -0
- package/dist/attacks/p0/lifecycle.js.map +1 -0
- package/dist/attacks/p0/target.d.ts +11 -0
- package/dist/attacks/p0/target.d.ts.map +1 -0
- package/dist/attacks/p0/target.js +177 -0
- package/dist/attacks/p0/target.js.map +1 -0
- package/dist/attacks/p0/tenant.d.ts +10 -0
- package/dist/attacks/p0/tenant.d.ts.map +1 -0
- package/dist/attacks/p0/tenant.js +155 -0
- package/dist/attacks/p0/tenant.js.map +1 -0
- package/dist/attacks/p0/types.d.ts +9 -0
- package/dist/attacks/p0/types.d.ts.map +1 -0
- package/dist/attacks/p0/types.js +2 -0
- package/dist/attacks/p0/types.js.map +1 -0
- package/dist/attacks/p1/approval.d.ts +5 -0
- package/dist/attacks/p1/approval.d.ts.map +1 -0
- package/dist/attacks/p1/approval.js +259 -0
- package/dist/attacks/p1/approval.js.map +1 -0
- package/dist/attacks/p1/audit.d.ts +4 -0
- package/dist/attacks/p1/audit.d.ts.map +1 -0
- package/dist/attacks/p1/audit.js +128 -0
- package/dist/attacks/p1/audit.js.map +1 -0
- package/dist/attacks/p1/authorization.d.ts +5 -0
- package/dist/attacks/p1/authorization.d.ts.map +1 -0
- package/dist/attacks/p1/authorization.js +239 -0
- package/dist/attacks/p1/authorization.js.map +1 -0
- package/dist/attacks/p1/index.d.ts +7 -0
- package/dist/attacks/p1/index.d.ts.map +1 -0
- package/dist/attacks/p1/index.js +7 -0
- package/dist/attacks/p1/index.js.map +1 -0
- package/dist/attacks/p1/race.d.ts +5 -0
- package/dist/attacks/p1/race.d.ts.map +1 -0
- package/dist/attacks/p1/race.js +255 -0
- package/dist/attacks/p1/race.js.map +1 -0
- package/dist/attacks/p1/replay.d.ts +6 -0
- package/dist/attacks/p1/replay.d.ts.map +1 -0
- package/dist/attacks/p1/replay.js +285 -0
- package/dist/attacks/p1/replay.js.map +1 -0
- package/dist/attacks/p1/types.d.ts +28 -0
- package/dist/attacks/p1/types.d.ts.map +1 -0
- package/dist/attacks/p1/types.js +2 -0
- package/dist/attacks/p1/types.js.map +1 -0
- package/dist/cli/config.d.ts +15 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +100 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/diagnostics.d.ts +4 -0
- package/dist/cli/diagnostics.d.ts.map +1 -0
- package/dist/cli/diagnostics.js +23 -0
- package/dist/cli/diagnostics.js.map +1 -0
- package/dist/cli/discovery.d.ts +3 -0
- package/dist/cli/discovery.d.ts.map +1 -0
- package/dist/cli/discovery.js +75 -0
- package/dist/cli/discovery.js.map +1 -0
- package/dist/cli/execution-catalog.d.ts +12 -0
- package/dist/cli/execution-catalog.d.ts.map +1 -0
- package/dist/cli/execution-catalog.js +76 -0
- package/dist/cli/execution-catalog.js.map +1 -0
- package/dist/cli/protocols.d.ts +6 -0
- package/dist/cli/protocols.d.ts.map +1 -0
- package/dist/cli/protocols.js +6 -0
- package/dist/cli/protocols.js.map +1 -0
- package/dist/cli/reporters.d.ts +7 -0
- package/dist/cli/reporters.d.ts.map +1 -0
- package/dist/cli/reporters.js +126 -0
- package/dist/cli/reporters.js.map +1 -0
- package/dist/cli/run-cli.d.ts +6 -0
- package/dist/cli/run-cli.d.ts.map +1 -0
- package/dist/cli/run-cli.js +243 -0
- package/dist/cli/run-cli.js.map +1 -0
- package/dist/cli/test-command.d.ts +29 -0
- package/dist/cli/test-command.d.ts.map +1 -0
- package/dist/cli/test-command.js +118 -0
- package/dist/cli/test-command.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +11 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/adapters.d.ts +23 -0
- package/dist/core/adapters.d.ts.map +1 -0
- package/dist/core/adapters.js +2 -0
- package/dist/core/adapters.js.map +1 -0
- package/dist/core/attacks.d.ts +29 -0
- package/dist/core/attacks.d.ts.map +1 -0
- package/dist/core/attacks.js +38 -0
- package/dist/core/attacks.js.map +1 -0
- package/dist/core/errors.d.ts +16 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +22 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/evidence.d.ts +18 -0
- package/dist/core/evidence.d.ts.map +1 -0
- package/dist/core/evidence.js +2 -0
- package/dist/core/evidence.js.map +1 -0
- package/dist/core/findings.d.ts +25 -0
- package/dist/core/findings.d.ts.map +1 -0
- package/dist/core/findings.js +4 -0
- package/dist/core/findings.js.map +1 -0
- package/dist/core/index.d.ts +10 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +10 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/provenance.d.ts +8 -0
- package/dist/core/provenance.d.ts.map +1 -0
- package/dist/core/provenance.js +2 -0
- package/dist/core/provenance.js.map +1 -0
- package/dist/core/redaction.d.ts +4 -0
- package/dist/core/redaction.d.ts.map +1 -0
- package/dist/core/redaction.js +59 -0
- package/dist/core/redaction.js.map +1 -0
- package/dist/core/runner.d.ts +42 -0
- package/dist/core/runner.d.ts.map +1 -0
- package/dist/core/runner.js +181 -0
- package/dist/core/runner.js.map +1 -0
- package/dist/core/security-context.d.ts +64 -0
- package/dist/core/security-context.d.ts.map +1 -0
- package/dist/core/security-context.js +56 -0
- package/dist/core/security-context.js.map +1 -0
- package/dist/github-action/core.d.ts +34 -0
- package/dist/github-action/core.d.ts.map +1 -0
- package/dist/github-action/core.js +118 -0
- package/dist/github-action/core.js.map +1 -0
- package/dist/github-action/run-action.d.ts +2 -0
- package/dist/github-action/run-action.d.ts.map +1 -0
- package/dist/github-action/run-action.js +112 -0
- package/dist/github-action/run-action.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/p0-fixture/a2a/executor.d.ts +22 -0
- package/dist/p0-fixture/a2a/executor.d.ts.map +1 -0
- package/dist/p0-fixture/a2a/executor.js +183 -0
- package/dist/p0-fixture/a2a/executor.js.map +1 -0
- package/dist/p0-fixture/a2a/harness.d.ts +16 -0
- package/dist/p0-fixture/a2a/harness.d.ts.map +1 -0
- package/dist/p0-fixture/a2a/harness.js +160 -0
- package/dist/p0-fixture/a2a/harness.js.map +1 -0
- package/dist/p0-fixture/authorization.d.ts +24 -0
- package/dist/p0-fixture/authorization.d.ts.map +1 -0
- package/dist/p0-fixture/authorization.js +66 -0
- package/dist/p0-fixture/authorization.js.map +1 -0
- package/dist/p0-fixture/constants.d.ts +17 -0
- package/dist/p0-fixture/constants.d.ts.map +1 -0
- package/dist/p0-fixture/constants.js +17 -0
- package/dist/p0-fixture/constants.js.map +1 -0
- package/dist/p0-fixture/handoff/adapter.d.ts +6 -0
- package/dist/p0-fixture/handoff/adapter.d.ts.map +1 -0
- package/dist/p0-fixture/handoff/adapter.js +8 -0
- package/dist/p0-fixture/handoff/adapter.js.map +1 -0
- package/dist/p0-fixture/index.d.ts +11 -0
- package/dist/p0-fixture/index.d.ts.map +1 -0
- package/dist/p0-fixture/index.js +11 -0
- package/dist/p0-fixture/index.js.map +1 -0
- package/dist/p0-fixture/mcp/fake-tools.d.ts +7 -0
- package/dist/p0-fixture/mcp/fake-tools.d.ts.map +1 -0
- package/dist/p0-fixture/mcp/fake-tools.js +322 -0
- package/dist/p0-fixture/mcp/fake-tools.js.map +1 -0
- package/dist/p0-fixture/mcp/harness.d.ts +16 -0
- package/dist/p0-fixture/mcp/harness.d.ts.map +1 -0
- package/dist/p0-fixture/mcp/harness.js +114 -0
- package/dist/p0-fixture/mcp/harness.js.map +1 -0
- package/dist/p0-fixture/mcp/types.d.ts +29 -0
- package/dist/p0-fixture/mcp/types.d.ts.map +1 -0
- package/dist/p0-fixture/mcp/types.js +2 -0
- package/dist/p0-fixture/mcp/types.js.map +1 -0
- package/dist/p0-fixture/payload-hash.d.ts +2 -0
- package/dist/p0-fixture/payload-hash.d.ts.map +1 -0
- package/dist/p0-fixture/payload-hash.js +20 -0
- package/dist/p0-fixture/payload-hash.js.map +1 -0
- package/dist/p0-fixture/reference.d.ts +8 -0
- package/dist/p0-fixture/reference.d.ts.map +1 -0
- package/dist/p0-fixture/reference.js +42 -0
- package/dist/p0-fixture/reference.js.map +1 -0
- package/dist/p0-fixture/scenario.d.ts +14 -0
- package/dist/p0-fixture/scenario.d.ts.map +1 -0
- package/dist/p0-fixture/scenario.js +22 -0
- package/dist/p0-fixture/scenario.js.map +1 -0
- package/dist/p0-fixture/state.d.ts +43 -0
- package/dist/p0-fixture/state.d.ts.map +1 -0
- package/dist/p0-fixture/state.js +85 -0
- package/dist/p0-fixture/state.js.map +1 -0
- package/dist/p0-fixture/target-adapter.d.ts +20 -0
- package/dist/p0-fixture/target-adapter.d.ts.map +1 -0
- package/dist/p0-fixture/target-adapter.js +62 -0
- package/dist/p0-fixture/target-adapter.js.map +1 -0
- package/dist/p1-fixture/approval-target-adapter.d.ts +47 -0
- package/dist/p1-fixture/approval-target-adapter.d.ts.map +1 -0
- package/dist/p1-fixture/approval-target-adapter.js +172 -0
- package/dist/p1-fixture/approval-target-adapter.js.map +1 -0
- package/dist/p1-fixture/audit-target-adapter.d.ts +36 -0
- package/dist/p1-fixture/audit-target-adapter.d.ts.map +1 -0
- package/dist/p1-fixture/audit-target-adapter.js +226 -0
- package/dist/p1-fixture/audit-target-adapter.js.map +1 -0
- package/dist/p1-fixture/barrier.d.ts +10 -0
- package/dist/p1-fixture/barrier.d.ts.map +1 -0
- package/dist/p1-fixture/barrier.js +44 -0
- package/dist/p1-fixture/barrier.js.map +1 -0
- package/dist/p1-fixture/clock.d.ts +7 -0
- package/dist/p1-fixture/clock.d.ts.map +1 -0
- package/dist/p1-fixture/clock.js +30 -0
- package/dist/p1-fixture/clock.js.map +1 -0
- package/dist/p1-fixture/index.d.ts +9 -0
- package/dist/p1-fixture/index.d.ts.map +1 -0
- package/dist/p1-fixture/index.js +9 -0
- package/dist/p1-fixture/index.js.map +1 -0
- package/dist/p1-fixture/race-target-adapter.d.ts +49 -0
- package/dist/p1-fixture/race-target-adapter.d.ts.map +1 -0
- package/dist/p1-fixture/race-target-adapter.js +384 -0
- package/dist/p1-fixture/race-target-adapter.js.map +1 -0
- package/dist/p1-fixture/replay-target-adapter.d.ts +44 -0
- package/dist/p1-fixture/replay-target-adapter.d.ts.map +1 -0
- package/dist/p1-fixture/replay-target-adapter.js +248 -0
- package/dist/p1-fixture/replay-target-adapter.js.map +1 -0
- package/dist/p1-fixture/state.d.ts +78 -0
- package/dist/p1-fixture/state.d.ts.map +1 -0
- package/dist/p1-fixture/state.js +191 -0
- package/dist/p1-fixture/state.js.map +1 -0
- package/dist/p1-fixture/target-adapter.d.ts +30 -0
- package/dist/p1-fixture/target-adapter.d.ts.map +1 -0
- package/dist/p1-fixture/target-adapter.js +142 -0
- package/dist/p1-fixture/target-adapter.js.map +1 -0
- package/dist/protocol-lab/a2a/executor.d.ts +13 -0
- package/dist/protocol-lab/a2a/executor.d.ts.map +1 -0
- package/dist/protocol-lab/a2a/executor.js +112 -0
- package/dist/protocol-lab/a2a/executor.js.map +1 -0
- package/dist/protocol-lab/a2a/harness.d.ts +11 -0
- package/dist/protocol-lab/a2a/harness.d.ts.map +1 -0
- package/dist/protocol-lab/a2a/harness.js +160 -0
- package/dist/protocol-lab/a2a/harness.js.map +1 -0
- package/dist/protocol-lab/evidence.d.ts +17 -0
- package/dist/protocol-lab/evidence.d.ts.map +1 -0
- package/dist/protocol-lab/evidence.js +28 -0
- package/dist/protocol-lab/evidence.js.map +1 -0
- package/dist/protocol-lab/fixture.d.ts +11 -0
- package/dist/protocol-lab/fixture.d.ts.map +1 -0
- package/dist/protocol-lab/fixture.js +54 -0
- package/dist/protocol-lab/fixture.js.map +1 -0
- package/dist/protocol-lab/handoff/adapter.d.ts +9 -0
- package/dist/protocol-lab/handoff/adapter.d.ts.map +1 -0
- package/dist/protocol-lab/handoff/adapter.js +13 -0
- package/dist/protocol-lab/handoff/adapter.js.map +1 -0
- package/dist/protocol-lab/handoff/translate.d.ts +3 -0
- package/dist/protocol-lab/handoff/translate.d.ts.map +1 -0
- package/dist/protocol-lab/handoff/translate.js +14 -0
- package/dist/protocol-lab/handoff/translate.js.map +1 -0
- package/dist/protocol-lab/mcp/fake-tools.d.ts +5 -0
- package/dist/protocol-lab/mcp/fake-tools.d.ts.map +1 -0
- package/dist/protocol-lab/mcp/fake-tools.js +58 -0
- package/dist/protocol-lab/mcp/fake-tools.js.map +1 -0
- package/dist/protocol-lab/mcp/harness.d.ts +7 -0
- package/dist/protocol-lab/mcp/harness.d.ts.map +1 -0
- package/dist/protocol-lab/mcp/harness.js +97 -0
- package/dist/protocol-lab/mcp/harness.js.map +1 -0
- package/dist/protocol-lab/models.d.ts +31 -0
- package/dist/protocol-lab/models.d.ts.map +1 -0
- package/dist/protocol-lab/models.js +2 -0
- package/dist/protocol-lab/models.js.map +1 -0
- package/dist/protocol-lab/run.d.ts +2 -0
- package/dist/protocol-lab/run.d.ts.map +1 -0
- package/dist/protocol-lab/run.js +22 -0
- package/dist/protocol-lab/run.js.map +1 -0
- package/dist/protocol-lab/target-adapter.d.ts +10 -0
- package/dist/protocol-lab/target-adapter.d.ts.map +1 -0
- package/dist/protocol-lab/target-adapter.js +33 -0
- package/dist/protocol-lab/target-adapter.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { P0_AUTHORIZED_DOWNSTREAM, P0_AUTHORIZED_RESOURCE, P0_AUTHORIZED_TENANT, P0_CALLER, P0_CAPABILITY_UPDATE, P0_PRINCIPAL, createP0ReferenceContext, createP0UpdateInvoiceScenario, } from '../../p0-fixture/index.js';
|
|
2
|
+
const FULL_CHAIN = [P0_PRINCIPAL, P0_CALLER, P0_AUTHORIZED_DOWNSTREAM];
|
|
3
|
+
function projectSources(section) {
|
|
4
|
+
return [
|
|
5
|
+
{
|
|
6
|
+
kind: 'project',
|
|
7
|
+
title: 'P1 Security Test Specification',
|
|
8
|
+
locator: `docs/P1_TEST_SPECIFICATION.md#${section}`,
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
kind: 'project',
|
|
12
|
+
title: 'Attack Catalog',
|
|
13
|
+
locator: 'docs/ATTACK_CATALOG.md#v01-p1--add-after-p0-engine-is-credible',
|
|
14
|
+
},
|
|
15
|
+
];
|
|
16
|
+
}
|
|
17
|
+
function createDefinition(input) {
|
|
18
|
+
return {
|
|
19
|
+
id: input.id,
|
|
20
|
+
name: input.name,
|
|
21
|
+
category: 'replay',
|
|
22
|
+
defaultSeverity: 'high',
|
|
23
|
+
priority: 'P1',
|
|
24
|
+
preconditions: input.preconditions,
|
|
25
|
+
mutationSteps: input.mutationSteps,
|
|
26
|
+
expectedInvariant: input.invariant,
|
|
27
|
+
evidenceRequirements: input.evidence,
|
|
28
|
+
applicability: {
|
|
29
|
+
a2a: ['1.0'],
|
|
30
|
+
mcp: ['2026-07-28'],
|
|
31
|
+
},
|
|
32
|
+
propertyClass: 'composition_responsibility',
|
|
33
|
+
sourceReferences: projectSources(input.section),
|
|
34
|
+
sideEffectClass: 'synthetic',
|
|
35
|
+
destructive: false,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function createUpdateContext() {
|
|
39
|
+
const context = createP0ReferenceContext();
|
|
40
|
+
if (context.upstreamAuthority === undefined || context.effectiveAuthority === undefined) {
|
|
41
|
+
throw new Error('P1 replay attacks require authority bindings.');
|
|
42
|
+
}
|
|
43
|
+
context.capabilities = [P0_CAPABILITY_UPDATE];
|
|
44
|
+
context.upstreamAuthority.capabilities = [P0_CAPABILITY_UPDATE];
|
|
45
|
+
context.effectiveAuthority.capabilities = [P0_CAPABILITY_UPDATE];
|
|
46
|
+
return context;
|
|
47
|
+
}
|
|
48
|
+
function relevantEvidenceSequences(result) {
|
|
49
|
+
const names = new Set([
|
|
50
|
+
'p1.replay.baseline',
|
|
51
|
+
'p1.replay.first_execution',
|
|
52
|
+
'p1.retry.acknowledgement_lost',
|
|
53
|
+
'p1.replay.classify',
|
|
54
|
+
'p1.replay.blocked',
|
|
55
|
+
'p1.replay.bypassed',
|
|
56
|
+
'p1.replay.second_execution',
|
|
57
|
+
'mcp.tool.call',
|
|
58
|
+
'mcp.tool.result',
|
|
59
|
+
]);
|
|
60
|
+
return result.evidence.filter((event) => names.has(event.event)).map((event) => event.sequence);
|
|
61
|
+
}
|
|
62
|
+
function evaluateReplay(result, messages) {
|
|
63
|
+
const output = result.output;
|
|
64
|
+
const evidenceSequences = relevantEvidenceSequences(result);
|
|
65
|
+
const firstDelta = output.sideEffectCounterAfterFirst - output.sideEffectCounterBefore;
|
|
66
|
+
if (!output.baselineExecuted || firstDelta !== 1) {
|
|
67
|
+
return {
|
|
68
|
+
status: 'inconclusive',
|
|
69
|
+
observedBehavior: 'The baseline protected action did not produce exactly one deterministic synthetic side effect.',
|
|
70
|
+
evidenceSequences,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const replayDelta = output.sideEffectCounterAfterSecond - output.sideEffectCounterAfterFirst;
|
|
74
|
+
if (!output.replayExecuted && replayDelta === 0) {
|
|
75
|
+
return {
|
|
76
|
+
status: 'pass',
|
|
77
|
+
observedBehavior: messages.pass,
|
|
78
|
+
evidenceSequences,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (output.replayExecuted && replayDelta === 1) {
|
|
82
|
+
return {
|
|
83
|
+
status: 'fail',
|
|
84
|
+
observedBehavior: messages.fail,
|
|
85
|
+
evidenceSequences,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
status: 'inconclusive',
|
|
90
|
+
observedBehavior: 'Replay execution and synthetic side-effect evidence could not establish a deterministic PASS or FAIL.',
|
|
91
|
+
evidenceSequences,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const REPLAY_001_DEFINITION = createDefinition({
|
|
95
|
+
id: 'HP-REPLAY-001',
|
|
96
|
+
name: 'Exact action replay',
|
|
97
|
+
preconditions: [
|
|
98
|
+
'A protected logical action executes once successfully.',
|
|
99
|
+
'Its authority is marked single-use.',
|
|
100
|
+
'The translated action can be replayed with the same logical action identity.',
|
|
101
|
+
],
|
|
102
|
+
mutationSteps: [
|
|
103
|
+
'Execute action:ACT-1001 once.',
|
|
104
|
+
'Record authority consumption and the first protected side effect.',
|
|
105
|
+
'Replay the identical logical action using a second execution attempt.',
|
|
106
|
+
],
|
|
107
|
+
invariant: 'A single-use protected logical action must not produce a second protected side effect when replayed.',
|
|
108
|
+
evidence: [
|
|
109
|
+
'logical action ID',
|
|
110
|
+
'first attempt ID',
|
|
111
|
+
'replay attempt ID',
|
|
112
|
+
'delegation ID',
|
|
113
|
+
'consumption state',
|
|
114
|
+
'side-effect counter before',
|
|
115
|
+
'side-effect counter after first execution',
|
|
116
|
+
'side-effect counter after replay',
|
|
117
|
+
],
|
|
118
|
+
section: 'hp-replay-001--exact-action-replay',
|
|
119
|
+
});
|
|
120
|
+
const REPLAY_002_DEFINITION = createDefinition({
|
|
121
|
+
id: 'HP-REPLAY-002',
|
|
122
|
+
name: 'Cross-context / cross-run replay',
|
|
123
|
+
preconditions: [
|
|
124
|
+
'Authority is explicitly bound to task:P1-TASK-A and run:P1-RUN-A.',
|
|
125
|
+
'The original context can execute the protected action.',
|
|
126
|
+
],
|
|
127
|
+
mutationSteps: [
|
|
128
|
+
'Capture the authority associated with the original task and run.',
|
|
129
|
+
'Reuse it under task:P1-TASK-B and run:P1-RUN-B without issuing a new grant.',
|
|
130
|
+
'Attempt the protected action in the new context.',
|
|
131
|
+
],
|
|
132
|
+
invariant: 'Authority bound to one explicit task/run context must not automatically authorize another task/run context.',
|
|
133
|
+
evidence: [
|
|
134
|
+
'original task and run',
|
|
135
|
+
'replay task and run',
|
|
136
|
+
'delegation ID',
|
|
137
|
+
'task/run binding decision',
|
|
138
|
+
'authorization result',
|
|
139
|
+
'protected side effect',
|
|
140
|
+
],
|
|
141
|
+
section: 'hp-replay-002--cross-context--cross-run-replay',
|
|
142
|
+
});
|
|
143
|
+
const REPLAY_003_DEFINITION = createDefinition({
|
|
144
|
+
id: 'HP-REPLAY-003',
|
|
145
|
+
name: 'Retry double execution',
|
|
146
|
+
preconditions: [
|
|
147
|
+
'One logical protected action can have multiple execution attempts.',
|
|
148
|
+
'The first attempt executes but its synthetic acknowledgement is lost.',
|
|
149
|
+
],
|
|
150
|
+
mutationSteps: [
|
|
151
|
+
'Execute attempt:ATT-1 for action:ACT-RETRY-1001.',
|
|
152
|
+
'Simulate loss of the acknowledgement after the side effect occurred.',
|
|
153
|
+
'Send attempt:ATT-2 as a retry for the same logical action.',
|
|
154
|
+
],
|
|
155
|
+
invariant: 'A retry representing the same logical protected action must not produce a second protected side effect.',
|
|
156
|
+
evidence: [
|
|
157
|
+
'logical action ID',
|
|
158
|
+
'attempt:ATT-1',
|
|
159
|
+
'attempt:ATT-2',
|
|
160
|
+
'acknowledgement ambiguity',
|
|
161
|
+
'retry classification',
|
|
162
|
+
'action completion state',
|
|
163
|
+
'side-effect counter before and after each attempt',
|
|
164
|
+
],
|
|
165
|
+
section: 'hp-replay-003--retry-double-execution',
|
|
166
|
+
});
|
|
167
|
+
const REPLAY_001_CASE = {
|
|
168
|
+
definition: REPLAY_001_DEFINITION,
|
|
169
|
+
evaluate(result) {
|
|
170
|
+
return evaluateReplay(result, {
|
|
171
|
+
pass: 'The exact replay was rejected after the single-use action was consumed, so no second synthetic side effect occurred.',
|
|
172
|
+
fail: 'The exact same consumed logical action executed again and produced a second protected synthetic side effect.',
|
|
173
|
+
});
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
const REPLAY_002_CASE = {
|
|
177
|
+
definition: REPLAY_002_DEFINITION,
|
|
178
|
+
evaluate(result) {
|
|
179
|
+
return evaluateReplay(result, {
|
|
180
|
+
pass: 'Authority captured from task/run A was rejected when replayed under task/run B.',
|
|
181
|
+
fail: 'Authority captured from task/run A was accepted under task/run B and produced another protected synthetic side effect.',
|
|
182
|
+
});
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
const REPLAY_003_CASE = {
|
|
186
|
+
definition: REPLAY_003_DEFINITION,
|
|
187
|
+
evaluate(result) {
|
|
188
|
+
return evaluateReplay(result, {
|
|
189
|
+
pass: 'The retry was recognized as the same completed logical action and did not create a second synthetic side effect.',
|
|
190
|
+
fail: 'The retry was treated as a new execution and produced a duplicate protected synthetic side effect.',
|
|
191
|
+
});
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
function createDelegation(input) {
|
|
195
|
+
return {
|
|
196
|
+
id: input.id,
|
|
197
|
+
principal: P0_PRINCIPAL,
|
|
198
|
+
delegate: P0_AUTHORIZED_DOWNSTREAM,
|
|
199
|
+
tenant: P0_AUTHORIZED_TENANT,
|
|
200
|
+
resources: [P0_AUTHORIZED_RESOURCE],
|
|
201
|
+
capabilities: [P0_CAPABILITY_UPDATE],
|
|
202
|
+
chain: [...FULL_CHAIN],
|
|
203
|
+
taskId: 'task:P1-TASK-A',
|
|
204
|
+
runId: 'run:P1-RUN-A',
|
|
205
|
+
issuedAt: 10,
|
|
206
|
+
expiresAt: 30,
|
|
207
|
+
singleUse: input.singleUse,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function createRequest(taskId, runId) {
|
|
211
|
+
return {
|
|
212
|
+
principal: P0_PRINCIPAL,
|
|
213
|
+
delegate: P0_AUTHORIZED_DOWNSTREAM,
|
|
214
|
+
tenant: P0_AUTHORIZED_TENANT,
|
|
215
|
+
resource: P0_AUTHORIZED_RESOURCE,
|
|
216
|
+
capability: P0_CAPABILITY_UPDATE,
|
|
217
|
+
taskId,
|
|
218
|
+
runId,
|
|
219
|
+
requiredChain: FULL_CHAIN,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
export const HP_REPLAY_001 = {
|
|
223
|
+
attack: REPLAY_001_CASE,
|
|
224
|
+
scenario: {
|
|
225
|
+
id: 'exact-action-replay',
|
|
226
|
+
kind: 'exact-action-replay',
|
|
227
|
+
actionId: 'action:ACT-1001',
|
|
228
|
+
firstAttemptId: 'attempt:ATT-1',
|
|
229
|
+
secondAttemptId: 'attempt:ATT-2',
|
|
230
|
+
delegation: createDelegation({
|
|
231
|
+
id: 'delegation:DEL-REPLAY-1001',
|
|
232
|
+
singleUse: true,
|
|
233
|
+
}),
|
|
234
|
+
baselineRequest: createRequest('task:P1-TASK-A', 'run:P1-RUN-A'),
|
|
235
|
+
replayRequest: createRequest('task:P1-TASK-A', 'run:P1-RUN-A'),
|
|
236
|
+
logicalTime: 15,
|
|
237
|
+
p0Scenario: createP0UpdateInvoiceScenario(24101),
|
|
238
|
+
},
|
|
239
|
+
createContext: createUpdateContext,
|
|
240
|
+
};
|
|
241
|
+
export const HP_REPLAY_002 = {
|
|
242
|
+
attack: REPLAY_002_CASE,
|
|
243
|
+
scenario: {
|
|
244
|
+
id: 'cross-context-replay',
|
|
245
|
+
kind: 'cross-context-replay',
|
|
246
|
+
actionId: 'action:ACT-CONTEXT-1001',
|
|
247
|
+
firstAttemptId: 'attempt:ATT-1',
|
|
248
|
+
secondAttemptId: 'attempt:ATT-2',
|
|
249
|
+
delegation: createDelegation({
|
|
250
|
+
id: 'delegation:DEL-REPLAY-1002',
|
|
251
|
+
singleUse: false,
|
|
252
|
+
}),
|
|
253
|
+
baselineRequest: createRequest('task:P1-TASK-A', 'run:P1-RUN-A'),
|
|
254
|
+
replayRequest: createRequest('task:P1-TASK-B', 'run:P1-RUN-B'),
|
|
255
|
+
logicalTime: 15,
|
|
256
|
+
p0Scenario: createP0UpdateInvoiceScenario(24102),
|
|
257
|
+
},
|
|
258
|
+
createContext: createUpdateContext,
|
|
259
|
+
};
|
|
260
|
+
export const HP_REPLAY_003 = {
|
|
261
|
+
attack: REPLAY_003_CASE,
|
|
262
|
+
scenario: {
|
|
263
|
+
id: 'retry-double-execution',
|
|
264
|
+
kind: 'retry-double-execution',
|
|
265
|
+
actionId: 'action:ACT-RETRY-1001',
|
|
266
|
+
firstAttemptId: 'attempt:ATT-1',
|
|
267
|
+
secondAttemptId: 'attempt:ATT-2',
|
|
268
|
+
delegation: createDelegation({
|
|
269
|
+
id: 'delegation:DEL-REPLAY-1003',
|
|
270
|
+
singleUse: false,
|
|
271
|
+
}),
|
|
272
|
+
baselineRequest: createRequest('task:P1-TASK-A', 'run:P1-RUN-A'),
|
|
273
|
+
replayRequest: createRequest('task:P1-TASK-A', 'run:P1-RUN-A'),
|
|
274
|
+
logicalTime: 15,
|
|
275
|
+
acknowledgementAmbiguity: true,
|
|
276
|
+
p0Scenario: createP0UpdateInvoiceScenario(24103),
|
|
277
|
+
},
|
|
278
|
+
createContext: createUpdateContext,
|
|
279
|
+
};
|
|
280
|
+
export const P1_REPLAY_ATTACKS = [
|
|
281
|
+
HP_REPLAY_001,
|
|
282
|
+
HP_REPLAY_002,
|
|
283
|
+
HP_REPLAY_003,
|
|
284
|
+
];
|
|
285
|
+
//# sourceMappingURL=replay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../../../src/attacks/p1/replay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AttackCase, SecurityContext } from '../../core/index.js';
|
|
2
|
+
import type { P1ApprovalScenario, P1AuditScenario, P1AuthorizationScenario, P1RaceScenario, P1ReplayScenario } from '../../p1-fixture/index.js';
|
|
3
|
+
export interface P1AttackPlan {
|
|
4
|
+
attack: AttackCase;
|
|
5
|
+
scenario: P1AuthorizationScenario;
|
|
6
|
+
createContext(): SecurityContext;
|
|
7
|
+
}
|
|
8
|
+
export interface P1ReplayAttackPlan {
|
|
9
|
+
attack: AttackCase;
|
|
10
|
+
scenario: P1ReplayScenario;
|
|
11
|
+
createContext(): SecurityContext;
|
|
12
|
+
}
|
|
13
|
+
export interface P1ApprovalAttackPlan {
|
|
14
|
+
attack: AttackCase;
|
|
15
|
+
scenario: P1ApprovalScenario;
|
|
16
|
+
createContext(): SecurityContext;
|
|
17
|
+
}
|
|
18
|
+
export interface P1RaceAttackPlan {
|
|
19
|
+
attack: AttackCase;
|
|
20
|
+
scenario: P1RaceScenario;
|
|
21
|
+
createContext(): SecurityContext;
|
|
22
|
+
}
|
|
23
|
+
export interface P1AuditAttackPlan {
|
|
24
|
+
attack: AttackCase;
|
|
25
|
+
scenario: P1AuditScenario;
|
|
26
|
+
createContext(): SecurityContext;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/attacks/p1/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,uBAAuB,EACvB,cAAc,EACd,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,uBAAuB,CAAC;IAClC,aAAa,IAAI,eAAe,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,aAAa,IAAI,eAAe,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,aAAa,IAAI,eAAe,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,aAAa,IAAI,eAAe,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,eAAe,CAAC;IAC1B,aAAa,IAAI,eAAe,CAAC;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/attacks/p1/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FindingSeverity } from '../core/index.js';
|
|
2
|
+
import type { CliTargetFixture } from './execution-catalog.js';
|
|
3
|
+
export type CliFailOn = FindingSeverity;
|
|
4
|
+
export type CliReporter = 'terminal' | 'json' | 'markdown';
|
|
5
|
+
export interface HandoffProbeConfig {
|
|
6
|
+
target?: CliTargetFixture;
|
|
7
|
+
tests?: readonly string[];
|
|
8
|
+
failOn?: CliFailOn;
|
|
9
|
+
reporter?: CliReporter;
|
|
10
|
+
output?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const DEFAULT_FAIL_ON: CliFailOn;
|
|
13
|
+
export declare function parseHandoffProbeConfig(value: unknown): HandoffProbeConfig;
|
|
14
|
+
export declare function loadHandoffProbeConfig(cwd: string): Promise<HandoffProbeConfig>;
|
|
15
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,MAAM,MAAM,SAAS,GAAG,eAAe,CAAC;AACxC,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,MAAM,GAAG,UAAU,CAAC;AAE3D,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,eAAe,EAAE,SAAkB,CAAC;AAoEjD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAsC1E;AAED,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAwBrF"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
export const DEFAULT_FAIL_ON = 'high';
|
|
4
|
+
const CONFIG_FILENAME = 'handoffprobe.config.json';
|
|
5
|
+
const ALLOWED_KEYS = new Set(['target', 'tests', 'failOn', 'reporter', 'output']);
|
|
6
|
+
const FAIL_ON_VALUES = ['info', 'low', 'medium', 'high', 'critical'];
|
|
7
|
+
const REPORTERS = ['terminal', 'json', 'markdown'];
|
|
8
|
+
function configError(message) {
|
|
9
|
+
return new Error(`${CONFIG_FILENAME}: ${message}`);
|
|
10
|
+
}
|
|
11
|
+
function isRecord(value) {
|
|
12
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
13
|
+
}
|
|
14
|
+
function parseTarget(value) {
|
|
15
|
+
if (value === 'secure' || value === 'vulnerable') {
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
throw configError('"target" must be "secure" or "vulnerable".');
|
|
19
|
+
}
|
|
20
|
+
function parseTests(value) {
|
|
21
|
+
if (!Array.isArray(value)) {
|
|
22
|
+
throw configError('"tests" must be an array of non-empty HP-ID strings.');
|
|
23
|
+
}
|
|
24
|
+
const tests = [];
|
|
25
|
+
for (const item of value) {
|
|
26
|
+
if (typeof item !== 'string' || item.trim().length === 0) {
|
|
27
|
+
throw configError('"tests" must be an array of non-empty HP-ID strings.');
|
|
28
|
+
}
|
|
29
|
+
tests.push(item);
|
|
30
|
+
}
|
|
31
|
+
return tests;
|
|
32
|
+
}
|
|
33
|
+
function parseFailOn(value) {
|
|
34
|
+
if (typeof value === 'string' && FAIL_ON_VALUES.includes(value)) {
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
throw configError('"failOn" must be info, low, medium, high, or critical.');
|
|
38
|
+
}
|
|
39
|
+
function parseReporter(value) {
|
|
40
|
+
if (typeof value === 'string' && REPORTERS.includes(value)) {
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
throw configError('"reporter" must be terminal, json, or markdown.');
|
|
44
|
+
}
|
|
45
|
+
function parseOutput(value) {
|
|
46
|
+
if (typeof value === 'string' && value.trim().length > 0) {
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
throw configError('"output" must be a non-empty string.');
|
|
50
|
+
}
|
|
51
|
+
export function parseHandoffProbeConfig(value) {
|
|
52
|
+
if (!isRecord(value)) {
|
|
53
|
+
throw configError('top-level value must be a JSON object.');
|
|
54
|
+
}
|
|
55
|
+
const unknownKeys = Object.keys(value)
|
|
56
|
+
.filter((key) => !ALLOWED_KEYS.has(key))
|
|
57
|
+
.sort();
|
|
58
|
+
if (unknownKeys.length > 0) {
|
|
59
|
+
throw configError(`unknown key${unknownKeys.length === 1 ? '' : 's'}: ${unknownKeys.join(', ')}.`);
|
|
60
|
+
}
|
|
61
|
+
const config = {};
|
|
62
|
+
if (value.target !== undefined) {
|
|
63
|
+
config.target = parseTarget(value.target);
|
|
64
|
+
}
|
|
65
|
+
if (value.tests !== undefined) {
|
|
66
|
+
config.tests = parseTests(value.tests);
|
|
67
|
+
}
|
|
68
|
+
if (value.failOn !== undefined) {
|
|
69
|
+
config.failOn = parseFailOn(value.failOn);
|
|
70
|
+
}
|
|
71
|
+
if (value.reporter !== undefined) {
|
|
72
|
+
config.reporter = parseReporter(value.reporter);
|
|
73
|
+
}
|
|
74
|
+
if (value.output !== undefined) {
|
|
75
|
+
config.output = parseOutput(value.output);
|
|
76
|
+
}
|
|
77
|
+
return config;
|
|
78
|
+
}
|
|
79
|
+
export async function loadHandoffProbeConfig(cwd) {
|
|
80
|
+
const path = join(cwd, CONFIG_FILENAME);
|
|
81
|
+
let source;
|
|
82
|
+
try {
|
|
83
|
+
source = await readFile(path, 'utf8');
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (error.code === 'ENOENT') {
|
|
87
|
+
return {};
|
|
88
|
+
}
|
|
89
|
+
throw configError('could not be read.');
|
|
90
|
+
}
|
|
91
|
+
let value;
|
|
92
|
+
try {
|
|
93
|
+
value = JSON.parse(source);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
throw configError('contains invalid JSON.');
|
|
97
|
+
}
|
|
98
|
+
return parseHandoffProbeConfig(value);
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type CliRuntimeFailureKind = 'scanner' | 'output';
|
|
2
|
+
export declare function sanitizeCliLine(value: string): string;
|
|
3
|
+
export declare function renderCliRuntimeDiagnostic(kind: CliRuntimeFailureKind, error: unknown): readonly string[];
|
|
4
|
+
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/cli/diagnostics.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEzD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,qBAAqB,EAC3B,KAAK,EAAE,OAAO,GACb,SAAS,MAAM,EAAE,CAmBnB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { HandoffProbeCoreError, redactText } from '../core/index.js';
|
|
2
|
+
export function sanitizeCliLine(value) {
|
|
3
|
+
return redactText(value).replace(/[\r\n]+/g, ' ');
|
|
4
|
+
}
|
|
5
|
+
export function renderCliRuntimeDiagnostic(kind, error) {
|
|
6
|
+
if (kind === 'output') {
|
|
7
|
+
return [
|
|
8
|
+
'HandoffProbe: output write failure.',
|
|
9
|
+
'Troubleshooting: check that the output parent directory exists and is writable.',
|
|
10
|
+
];
|
|
11
|
+
}
|
|
12
|
+
if (error instanceof HandoffProbeCoreError) {
|
|
13
|
+
return [
|
|
14
|
+
`HandoffProbe: scanner runtime failure (${error.code} at ${sanitizeCliLine(error.stage)}).`,
|
|
15
|
+
'Troubleshooting: verify the selected target/adapter and rerun the same command.',
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
return [
|
|
19
|
+
'HandoffProbe: scanner runtime failure.',
|
|
20
|
+
'Troubleshooting: rerun the same command; if it repeats, report the command and HandoffProbe version.',
|
|
21
|
+
];
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/cli/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAIrE,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,IAA2B,EAC3B,KAAc;IAEd,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO;YACL,qCAAqC;YACrC,iFAAiF;SAClF,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,YAAY,qBAAqB,EAAE,CAAC;QAC3C,OAAO;YACL,0CAA0C,KAAK,CAAC,IAAI,OAAO,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI;YAC3F,iFAAiF;SAClF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,wCAAwC;QACxC,sGAAsG;KACvG,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/cli/discovery.ts"],"names":[],"mappings":"AAwBA,wBAAgB,gBAAgB,IAAI,MAAM,CAoCzC;AAED,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAsCtE"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { CLI_EXECUTION_CATALOG, getCliExecutionBinding } from './execution-catalog.js';
|
|
2
|
+
function upper(value) {
|
|
3
|
+
return value.toUpperCase();
|
|
4
|
+
}
|
|
5
|
+
function numbered(values) {
|
|
6
|
+
return values.map((value, index) => ` ${index + 1}. ${value}`);
|
|
7
|
+
}
|
|
8
|
+
function bullets(values) {
|
|
9
|
+
return values.map((value) => ` - ${value}`);
|
|
10
|
+
}
|
|
11
|
+
function renderSource(definition) {
|
|
12
|
+
return definition.sourceReferences.map((source) => {
|
|
13
|
+
const version = source.version === undefined ? '' : ` (${source.version})`;
|
|
14
|
+
return ` - [${source.kind}] ${source.title}${version} — ${source.locator}`;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export function renderAttackList() {
|
|
18
|
+
const definitions = CLI_EXECUTION_CATALOG.map((binding) => binding.definition);
|
|
19
|
+
const idWidth = Math.max('ID'.length, ...definitions.map((definition) => definition.id.length));
|
|
20
|
+
const priorityWidth = Math.max('PRIORITY'.length, ...definitions.map((definition) => definition.priority.length));
|
|
21
|
+
const severityWidth = Math.max('SEVERITY'.length, ...definitions.map((definition) => definition.defaultSeverity.length));
|
|
22
|
+
const categoryWidth = Math.max('CATEGORY'.length, ...definitions.map((definition) => definition.category.length));
|
|
23
|
+
const header = [
|
|
24
|
+
'ID'.padEnd(idWidth),
|
|
25
|
+
'PRIORITY'.padEnd(priorityWidth),
|
|
26
|
+
'SEVERITY'.padEnd(severityWidth),
|
|
27
|
+
'CATEGORY'.padEnd(categoryWidth),
|
|
28
|
+
'NAME',
|
|
29
|
+
].join(' ');
|
|
30
|
+
const rows = definitions.map((definition) => [
|
|
31
|
+
definition.id.padEnd(idWidth),
|
|
32
|
+
definition.priority.padEnd(priorityWidth),
|
|
33
|
+
upper(definition.defaultSeverity).padEnd(severityWidth),
|
|
34
|
+
definition.category.padEnd(categoryWidth),
|
|
35
|
+
definition.name,
|
|
36
|
+
].join(' '));
|
|
37
|
+
return [`HandoffProbe attacks (${definitions.length})`, '', header, ...rows].join('\n');
|
|
38
|
+
}
|
|
39
|
+
export function renderAttackExplanation(id) {
|
|
40
|
+
const binding = getCliExecutionBinding(id);
|
|
41
|
+
if (binding === undefined) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
const definition = binding.definition;
|
|
45
|
+
return [
|
|
46
|
+
`${definition.id} — ${definition.name}`,
|
|
47
|
+
'',
|
|
48
|
+
`Priority: ${definition.priority}`,
|
|
49
|
+
`Severity: ${upper(definition.defaultSeverity)}`,
|
|
50
|
+
`Category: ${definition.category}`,
|
|
51
|
+
`Property class: ${definition.propertyClass}`,
|
|
52
|
+
`Side effects: ${definition.sideEffectClass}`,
|
|
53
|
+
`Destructive: ${definition.destructive ? 'yes' : 'no'}`,
|
|
54
|
+
'',
|
|
55
|
+
'Protocols:',
|
|
56
|
+
` A2A: ${definition.applicability.a2a.join(', ') || 'not applicable'}`,
|
|
57
|
+
` MCP: ${definition.applicability.mcp.join(', ') || 'not applicable'}`,
|
|
58
|
+
'',
|
|
59
|
+
'Expected invariant:',
|
|
60
|
+
` ${definition.expectedInvariant}`,
|
|
61
|
+
'',
|
|
62
|
+
'Preconditions:',
|
|
63
|
+
...numbered(definition.preconditions),
|
|
64
|
+
'',
|
|
65
|
+
'Mutation steps:',
|
|
66
|
+
...numbered(definition.mutationSteps),
|
|
67
|
+
'',
|
|
68
|
+
'Required evidence:',
|
|
69
|
+
...bullets(definition.evidenceRequirements),
|
|
70
|
+
'',
|
|
71
|
+
'Sources:',
|
|
72
|
+
...renderSource(definition),
|
|
73
|
+
].join('\n');
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/cli/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AttackCase, AttackDefinition, SecurityContext, TargetAdapter } from '../core/index.js';
|
|
2
|
+
export type CliTargetFixture = 'secure' | 'vulnerable';
|
|
3
|
+
export interface CliExecutionBinding {
|
|
4
|
+
readonly attack: AttackCase;
|
|
5
|
+
readonly definition: AttackDefinition;
|
|
6
|
+
createContext(): SecurityContext;
|
|
7
|
+
createTarget(fixture: CliTargetFixture): TargetAdapter;
|
|
8
|
+
}
|
|
9
|
+
export declare const CLI_EXECUTION_CATALOG: readonly CliExecutionBinding[];
|
|
10
|
+
export declare const CLI_EXECUTION_CATALOG_BY_ID: ReadonlyMap<string, CliExecutionBinding>;
|
|
11
|
+
export declare function getCliExecutionBinding(id: string): CliExecutionBinding | undefined;
|
|
12
|
+
//# sourceMappingURL=execution-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-catalog.d.ts","sourceRoot":"","sources":["../../src/cli/execution-catalog.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EACd,MAAM,kBAAkB,CAAC;AAY1B,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IAEtC,aAAa,IAAI,eAAe,CAAC;IACjC,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,aAAa,CAAC;CACxD;AA8GD,eAAO,MAAM,qBAAqB,EAAE,SAAS,mBAAmB,EAAY,CAAC;AAE7E,eAAO,MAAM,2BAA2B,EAAE,WAAW,CAAC,MAAM,EAAE,mBAAmB,CAEhF,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAElF"}
|