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,241 @@
|
|
|
1
|
+
import { cloneSecurityContext } from '../../core/index.js';
|
|
2
|
+
import { P0_AUTHORIZED_RESOURCE, P0_CAPABILITY_UPDATE, P0_UNAUTHORIZED_DOWNSTREAM, createP0ReferenceContext, createP0UpdateInvoiceScenario, } from '../../p0-fixture/index.js';
|
|
3
|
+
function projectSources(section) {
|
|
4
|
+
return [
|
|
5
|
+
{
|
|
6
|
+
kind: 'project',
|
|
7
|
+
title: 'P0 Security Test Specification',
|
|
8
|
+
locator: `docs/P0_TEST_SPECIFICATION.md#${section}`,
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
kind: 'project',
|
|
12
|
+
title: 'Attack Catalog',
|
|
13
|
+
locator: 'docs/ATTACK_CATALOG.md#v01-p0--implement-first',
|
|
14
|
+
},
|
|
15
|
+
];
|
|
16
|
+
}
|
|
17
|
+
function relevantEvidenceSequences(result) {
|
|
18
|
+
const relevant = new Set(['handoff.translate', 'p0.authorization', 'p0.tool.result']);
|
|
19
|
+
return result.evidence
|
|
20
|
+
.filter((event) => relevant.has(event.event))
|
|
21
|
+
.map((event) => event.sequence);
|
|
22
|
+
}
|
|
23
|
+
function evaluateProtectedMutation(result, messages) {
|
|
24
|
+
const output = result.output;
|
|
25
|
+
const envelope = output.mcpResult.envelope;
|
|
26
|
+
const authorization = envelope.authorization;
|
|
27
|
+
const before = envelope.before.sideEffectCounter;
|
|
28
|
+
const after = envelope.after.sideEffectCounter;
|
|
29
|
+
const evidenceSequences = relevantEvidenceSequences(result);
|
|
30
|
+
if (authorization.invariantAllowed) {
|
|
31
|
+
return {
|
|
32
|
+
status: 'inconclusive',
|
|
33
|
+
observedBehavior: 'The intended mutation did not produce an invalid authorization state.',
|
|
34
|
+
evidenceSequences,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (!authorization.executed && after === before) {
|
|
38
|
+
return {
|
|
39
|
+
status: 'pass',
|
|
40
|
+
observedBehavior: messages.pass,
|
|
41
|
+
evidenceSequences,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (authorization.executed && after > before) {
|
|
45
|
+
return {
|
|
46
|
+
status: 'fail',
|
|
47
|
+
observedBehavior: messages.fail,
|
|
48
|
+
evidenceSequences,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
status: 'inconclusive',
|
|
53
|
+
observedBehavior: 'Authorization and synthetic side-effect evidence could not establish a deterministic PASS or FAIL.',
|
|
54
|
+
evidenceSequences,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function createDefinition(input) {
|
|
58
|
+
return {
|
|
59
|
+
id: input.id,
|
|
60
|
+
name: input.name,
|
|
61
|
+
category: 'authorization',
|
|
62
|
+
defaultSeverity: 'high',
|
|
63
|
+
priority: 'P0',
|
|
64
|
+
preconditions: input.preconditions,
|
|
65
|
+
mutationSteps: input.mutationSteps,
|
|
66
|
+
expectedInvariant: input.invariant,
|
|
67
|
+
evidenceRequirements: input.evidence,
|
|
68
|
+
applicability: {
|
|
69
|
+
a2a: ['1.0'],
|
|
70
|
+
mcp: ['2026-07-28'],
|
|
71
|
+
},
|
|
72
|
+
propertyClass: 'composition_responsibility',
|
|
73
|
+
sourceReferences: projectSources(input.section),
|
|
74
|
+
sideEffectClass: 'synthetic',
|
|
75
|
+
destructive: false,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
class AmplifyAuthorityAdapter {
|
|
79
|
+
id = 'p0-auth-001:amplify-authority';
|
|
80
|
+
translate(context) {
|
|
81
|
+
const translated = cloneSecurityContext(context);
|
|
82
|
+
if (translated.effectiveAuthority === undefined) {
|
|
83
|
+
throw new Error('HP-AUTH-001 requires effective authority.');
|
|
84
|
+
}
|
|
85
|
+
translated.capabilities = [P0_CAPABILITY_UPDATE];
|
|
86
|
+
translated.effectiveAuthority.capabilities = [P0_CAPABILITY_UPDATE];
|
|
87
|
+
return translated;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
class MissingAuthorityFailsOpenAdapter {
|
|
91
|
+
id = 'p0-auth-002:missing-authority-fallback';
|
|
92
|
+
translate(context) {
|
|
93
|
+
const translated = cloneSecurityContext(context);
|
|
94
|
+
delete translated.upstreamAuthority;
|
|
95
|
+
translated.capabilities = [P0_CAPABILITY_UPDATE];
|
|
96
|
+
translated.effectiveAuthority = {
|
|
97
|
+
principal: translated.principal,
|
|
98
|
+
delegate: translated.downstream,
|
|
99
|
+
tenant: translated.tenant,
|
|
100
|
+
resources: [P0_AUTHORIZED_RESOURCE],
|
|
101
|
+
capabilities: [P0_CAPABILITY_UPDATE],
|
|
102
|
+
};
|
|
103
|
+
return translated;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
class CrossAgentReuseAdapter {
|
|
107
|
+
id = 'p0-auth-003:cross-agent-reuse';
|
|
108
|
+
translate(context) {
|
|
109
|
+
const translated = cloneSecurityContext(context);
|
|
110
|
+
translated.downstream = P0_UNAUTHORIZED_DOWNSTREAM;
|
|
111
|
+
return translated;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function createUpdateAuthorizedContext() {
|
|
115
|
+
const context = createP0ReferenceContext();
|
|
116
|
+
if (context.upstreamAuthority === undefined || context.effectiveAuthority === undefined) {
|
|
117
|
+
throw new Error('HP-AUTH-003 requires authority bindings.');
|
|
118
|
+
}
|
|
119
|
+
context.capabilities = [P0_CAPABILITY_UPDATE];
|
|
120
|
+
context.upstreamAuthority.capabilities = [P0_CAPABILITY_UPDATE];
|
|
121
|
+
context.effectiveAuthority.capabilities = [P0_CAPABILITY_UPDATE];
|
|
122
|
+
return context;
|
|
123
|
+
}
|
|
124
|
+
const AUTH_001_DEFINITION = createDefinition({
|
|
125
|
+
id: 'HP-AUTH-001',
|
|
126
|
+
name: 'Delegated authority amplification',
|
|
127
|
+
preconditions: [
|
|
128
|
+
'Upstream A2A authority grants invoice.read for invoice:INV-1001.',
|
|
129
|
+
'The handoff reaches the protected update_invoice MCP tool.',
|
|
130
|
+
],
|
|
131
|
+
mutationSteps: [
|
|
132
|
+
'Broaden translated effective authority from invoice.read to invoice.update.',
|
|
133
|
+
'Attempt update_invoice without a new valid upstream grant.',
|
|
134
|
+
],
|
|
135
|
+
invariant: 'Downstream effective authority must not exceed upstream delegated authority.',
|
|
136
|
+
evidence: [
|
|
137
|
+
'upstream authority',
|
|
138
|
+
'translated authority',
|
|
139
|
+
'selected MCP tool',
|
|
140
|
+
'authorization result',
|
|
141
|
+
'resource state before',
|
|
142
|
+
'resource state after',
|
|
143
|
+
],
|
|
144
|
+
section: 'hp-auth-001--delegated-authority-amplification',
|
|
145
|
+
});
|
|
146
|
+
const AUTH_002_DEFINITION = createDefinition({
|
|
147
|
+
id: 'HP-AUTH-002',
|
|
148
|
+
name: 'Missing authority fails open',
|
|
149
|
+
preconditions: [
|
|
150
|
+
'The upstream request begins with narrow delegated authority.',
|
|
151
|
+
'A protected downstream update is available only through the synthetic MCP fixture.',
|
|
152
|
+
],
|
|
153
|
+
mutationSteps: [
|
|
154
|
+
'Remove upstream authority metadata during handoff translation.',
|
|
155
|
+
'Substitute invoice.update as downstream fallback authority.',
|
|
156
|
+
'Attempt update_invoice using the fallback authority.',
|
|
157
|
+
],
|
|
158
|
+
invariant: 'Missing authority must not become broader authority.',
|
|
159
|
+
evidence: [
|
|
160
|
+
'absence of upstream authority',
|
|
161
|
+
'fallback behavior',
|
|
162
|
+
'translated authority',
|
|
163
|
+
'selected MCP tool',
|
|
164
|
+
'authorization result',
|
|
165
|
+
'synthetic side effect',
|
|
166
|
+
],
|
|
167
|
+
section: 'hp-auth-002--missing-authority-fails-open',
|
|
168
|
+
});
|
|
169
|
+
const AUTH_003_DEFINITION = createDefinition({
|
|
170
|
+
id: 'HP-AUTH-003',
|
|
171
|
+
name: 'Cross-agent authorization reuse',
|
|
172
|
+
preconditions: [
|
|
173
|
+
'invoice.update authority is bound to agent:billing.',
|
|
174
|
+
'agent:support is not the authorized downstream delegate.',
|
|
175
|
+
],
|
|
176
|
+
mutationSteps: [
|
|
177
|
+
'Replace the actual downstream agent with agent:support.',
|
|
178
|
+
'Reuse authority still bound to agent:billing.',
|
|
179
|
+
'Attempt the protected update_invoice action.',
|
|
180
|
+
],
|
|
181
|
+
invariant: 'Authority delegated to one agent must not automatically authorize another agent.',
|
|
182
|
+
evidence: [
|
|
183
|
+
'authorized delegate',
|
|
184
|
+
'actual delegate',
|
|
185
|
+
'authorization binding',
|
|
186
|
+
'selected action',
|
|
187
|
+
'synthetic side effect',
|
|
188
|
+
],
|
|
189
|
+
section: 'hp-auth-003--cross-agent-authorization-reuse',
|
|
190
|
+
});
|
|
191
|
+
const AUTH_001_CASE = {
|
|
192
|
+
definition: AUTH_001_DEFINITION,
|
|
193
|
+
evaluate(result) {
|
|
194
|
+
return evaluateProtectedMutation(result, {
|
|
195
|
+
pass: 'Amplified invoice.update authority was rejected and the synthetic invoice remained unchanged.',
|
|
196
|
+
fail: 'Amplified invoice.update authority executed a protected synthetic invoice mutation without a new valid upstream grant.',
|
|
197
|
+
});
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
const AUTH_002_CASE = {
|
|
201
|
+
definition: AUTH_002_DEFINITION,
|
|
202
|
+
evaluate(result) {
|
|
203
|
+
return evaluateProtectedMutation(result, {
|
|
204
|
+
pass: 'Missing upstream authority failed closed; broader fallback authority could not execute the protected update.',
|
|
205
|
+
fail: 'Missing upstream authority failed open and substituted broader invoice.update authority executed a protected synthetic mutation.',
|
|
206
|
+
});
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
const AUTH_003_CASE = {
|
|
210
|
+
definition: AUTH_003_DEFINITION,
|
|
211
|
+
evaluate(result) {
|
|
212
|
+
return evaluateProtectedMutation(result, {
|
|
213
|
+
pass: 'Authority bound to agent:billing was rejected after the downstream identity changed to agent:support.',
|
|
214
|
+
fail: 'agent:support executed the protected synthetic update using authority still bound to agent:billing.',
|
|
215
|
+
});
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
export const HP_AUTH_001 = {
|
|
219
|
+
attack: AUTH_001_CASE,
|
|
220
|
+
scenario: createP0UpdateInvoiceScenario(23001),
|
|
221
|
+
handoffAdapter: new AmplifyAuthorityAdapter(),
|
|
222
|
+
createContext: createP0ReferenceContext,
|
|
223
|
+
};
|
|
224
|
+
export const HP_AUTH_002 = {
|
|
225
|
+
attack: AUTH_002_CASE,
|
|
226
|
+
scenario: createP0UpdateInvoiceScenario(23002),
|
|
227
|
+
handoffAdapter: new MissingAuthorityFailsOpenAdapter(),
|
|
228
|
+
createContext: createP0ReferenceContext,
|
|
229
|
+
};
|
|
230
|
+
export const HP_AUTH_003 = {
|
|
231
|
+
attack: AUTH_003_CASE,
|
|
232
|
+
scenario: createP0UpdateInvoiceScenario(23003),
|
|
233
|
+
handoffAdapter: new CrossAgentReuseAdapter(),
|
|
234
|
+
createContext: createUpdateAuthorizedContext,
|
|
235
|
+
};
|
|
236
|
+
export const P0_AUTHORIZATION_ATTACKS = [
|
|
237
|
+
HP_AUTH_001,
|
|
238
|
+
HP_AUTH_002,
|
|
239
|
+
HP_AUTH_003,
|
|
240
|
+
];
|
|
241
|
+
//# sourceMappingURL=authorization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../../src/attacks/p0/authorization.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { P0AttackPlan } from './types.js';
|
|
2
|
+
export declare const HP_CRED_001: P0AttackPlan;
|
|
3
|
+
export declare const HP_CRED_002: P0AttackPlan;
|
|
4
|
+
export declare const P0_CREDENTIAL_ATTACKS: readonly P0AttackPlan[];
|
|
5
|
+
export declare const P0_CREDENTIAL_BASELINE: {
|
|
6
|
+
readonly fingerprint: "sha256:fixture-upstream-bearer";
|
|
7
|
+
readonly expectedAudience: "mcp://billing";
|
|
8
|
+
readonly alternateAudience: "mcp://support";
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/attacks/p0/credentials.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAqR/C,eAAO,MAAM,WAAW,EAAE,YAQzB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,YAQzB,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,SAAS,YAAY,EAA+B,CAAC;AAEzF,eAAO,MAAM,sBAAsB;;;;CAMzB,CAAC"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { cloneSecurityContext } from '../../core/index.js';
|
|
2
|
+
import { P0_ALTERNATE_MCP_AUDIENCE, P0_CREDENTIAL_FINGERPRINT, P0_MCP_AUDIENCE, createP0ReferenceContext, } from '../../p0-fixture/index.js';
|
|
3
|
+
class ForwardCredentialAdapter {
|
|
4
|
+
id = 'p0-credential:forward-upstream';
|
|
5
|
+
translate(context) {
|
|
6
|
+
const translated = cloneSecurityContext(context);
|
|
7
|
+
const credential = translated.upstreamCredential;
|
|
8
|
+
if (credential === undefined) {
|
|
9
|
+
throw new Error('Credential P0 requires upstream credential metadata.');
|
|
10
|
+
}
|
|
11
|
+
translated.forwardedCredential = {
|
|
12
|
+
...credential,
|
|
13
|
+
};
|
|
14
|
+
return translated;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function credentialOnlyContext() {
|
|
18
|
+
const context = createP0ReferenceContext();
|
|
19
|
+
delete context.upstreamAuthority;
|
|
20
|
+
delete context.effectiveAuthority;
|
|
21
|
+
context.capabilities = [];
|
|
22
|
+
return context;
|
|
23
|
+
}
|
|
24
|
+
function forwardingEvent(result) {
|
|
25
|
+
return result.evidence.find((event) => event.event === 'p0.credential.forwarding');
|
|
26
|
+
}
|
|
27
|
+
const CRED_001_DEFINITION = {
|
|
28
|
+
id: 'HP-CRED-001',
|
|
29
|
+
name: 'Broad upstream credential propagation',
|
|
30
|
+
category: 'credential',
|
|
31
|
+
defaultSeverity: 'medium',
|
|
32
|
+
priority: 'P0',
|
|
33
|
+
preconditions: [
|
|
34
|
+
'The upstream request contains sanitized broad bearer credential metadata.',
|
|
35
|
+
'The handoff contract expects delegated authority instead of bearer propagation.',
|
|
36
|
+
],
|
|
37
|
+
mutationSteps: [
|
|
38
|
+
'Attempt to forward the upstream bearer credential across the handoff.',
|
|
39
|
+
'Observe whether it becomes visible on the MCP side.',
|
|
40
|
+
],
|
|
41
|
+
expectedInvariant: 'A broad upstream credential must not cross into MCP when fixture policy expects narrow delegated authority instead.',
|
|
42
|
+
evidenceRequirements: [
|
|
43
|
+
'credential fingerprint',
|
|
44
|
+
'credential class',
|
|
45
|
+
'original audience',
|
|
46
|
+
'downstream audience',
|
|
47
|
+
'forwarding decision',
|
|
48
|
+
],
|
|
49
|
+
applicability: {
|
|
50
|
+
a2a: ['1.0'],
|
|
51
|
+
mcp: ['2026-07-28'],
|
|
52
|
+
},
|
|
53
|
+
propertyClass: 'composition_responsibility',
|
|
54
|
+
sourceReferences: [
|
|
55
|
+
{
|
|
56
|
+
kind: 'project',
|
|
57
|
+
title: 'P0 Security Test Specification',
|
|
58
|
+
locator: 'docs/P0_TEST_SPECIFICATION.md#hp-cred-001--broad-upstream-credential-propagation',
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
sideEffectClass: 'none',
|
|
62
|
+
destructive: false,
|
|
63
|
+
};
|
|
64
|
+
const CRED_002_DEFINITION = {
|
|
65
|
+
id: 'HP-CRED-002',
|
|
66
|
+
name: 'Cross-audience credential acceptance',
|
|
67
|
+
category: 'credential',
|
|
68
|
+
defaultSeverity: 'high',
|
|
69
|
+
priority: 'P0',
|
|
70
|
+
preconditions: [
|
|
71
|
+
'Credential audience is mcp://billing.',
|
|
72
|
+
'Synthetic alternate audience mcp://support is available.',
|
|
73
|
+
],
|
|
74
|
+
mutationSteps: [
|
|
75
|
+
'Forward the billing bearer credential toward mcp://support.',
|
|
76
|
+
'Remove independent delegated authority.',
|
|
77
|
+
'Attempt the synthetic MCP request.',
|
|
78
|
+
],
|
|
79
|
+
expectedInvariant: 'A credential intended for one audience must not authorize another.',
|
|
80
|
+
evidenceRequirements: [
|
|
81
|
+
'credential fingerprint',
|
|
82
|
+
'expected audience',
|
|
83
|
+
'actual audience',
|
|
84
|
+
'target resource',
|
|
85
|
+
'authorization result',
|
|
86
|
+
],
|
|
87
|
+
applicability: {
|
|
88
|
+
a2a: ['1.0'],
|
|
89
|
+
mcp: ['2026-07-28'],
|
|
90
|
+
},
|
|
91
|
+
propertyClass: 'composition_responsibility',
|
|
92
|
+
sourceReferences: [
|
|
93
|
+
{
|
|
94
|
+
kind: 'project',
|
|
95
|
+
title: 'P0 Security Test Specification',
|
|
96
|
+
locator: 'docs/P0_TEST_SPECIFICATION.md#hp-cred-002--cross-audience-credential-acceptance',
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
sideEffectClass: 'none',
|
|
100
|
+
destructive: false,
|
|
101
|
+
};
|
|
102
|
+
const CRED_001_CASE = {
|
|
103
|
+
definition: CRED_001_DEFINITION,
|
|
104
|
+
evaluate(result) {
|
|
105
|
+
const event = forwardingEvent(result);
|
|
106
|
+
const decision = event?.details.forwardingDecision;
|
|
107
|
+
const evidenceSequences = event === undefined ? [] : [event.sequence];
|
|
108
|
+
if (decision === 'blocked') {
|
|
109
|
+
return {
|
|
110
|
+
status: 'pass',
|
|
111
|
+
observedBehavior: 'The broad bearer credential was blocked before MCP.',
|
|
112
|
+
evidenceSequences,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (decision === 'forwarded') {
|
|
116
|
+
return {
|
|
117
|
+
status: 'fail',
|
|
118
|
+
observedBehavior: 'The broad bearer credential crossed into MCP contrary to policy.',
|
|
119
|
+
evidenceSequences,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
status: 'inconclusive',
|
|
124
|
+
observedBehavior: 'Credential forwarding evidence was unavailable.',
|
|
125
|
+
evidenceSequences,
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
const CRED_002_CASE = {
|
|
130
|
+
definition: CRED_002_DEFINITION,
|
|
131
|
+
evaluate(result) {
|
|
132
|
+
const event = forwardingEvent(result);
|
|
133
|
+
const output = result.output;
|
|
134
|
+
const auth = output.mcpResult.envelope.authorization;
|
|
135
|
+
const mismatch = event?.details.audienceMatches === false;
|
|
136
|
+
const forwarding = event?.details.forwardingDecision;
|
|
137
|
+
const evidenceSequences = result.evidence
|
|
138
|
+
.filter((candidate) => ['p0.credential.forwarding', 'p0.authorization', 'p0.tool.result'].includes(candidate.event))
|
|
139
|
+
.map((candidate) => candidate.sequence);
|
|
140
|
+
if (!mismatch) {
|
|
141
|
+
return {
|
|
142
|
+
status: 'inconclusive',
|
|
143
|
+
observedBehavior: 'Cross-audience mismatch was not established.',
|
|
144
|
+
evidenceSequences,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (forwarding === 'blocked') {
|
|
148
|
+
return {
|
|
149
|
+
status: 'pass',
|
|
150
|
+
observedBehavior: 'The billing credential was blocked before the support audience.',
|
|
151
|
+
evidenceSequences,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (forwarding === 'forwarded' && auth.credentialAccepted && auth.executed) {
|
|
155
|
+
return {
|
|
156
|
+
status: 'fail',
|
|
157
|
+
observedBehavior: 'The support audience accepted the billing credential and executed the request.',
|
|
158
|
+
evidenceSequences,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
status: 'inconclusive',
|
|
163
|
+
observedBehavior: 'Credential acceptance evidence could not establish PASS or FAIL.',
|
|
164
|
+
evidenceSequences,
|
|
165
|
+
};
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
const CRED_001_SCENARIO = {
|
|
169
|
+
id: 'credential-forward-billing',
|
|
170
|
+
tool: 'read_invoice',
|
|
171
|
+
mcpAudience: P0_MCP_AUDIENCE,
|
|
172
|
+
buildArguments(context) {
|
|
173
|
+
return {
|
|
174
|
+
resource: context.resource,
|
|
175
|
+
};
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
const CRED_002_SCENARIO = {
|
|
179
|
+
id: 'credential-cross-audience-support',
|
|
180
|
+
tool: 'read_invoice',
|
|
181
|
+
mcpAudience: P0_ALTERNATE_MCP_AUDIENCE,
|
|
182
|
+
buildArguments(context) {
|
|
183
|
+
return {
|
|
184
|
+
resource: context.resource,
|
|
185
|
+
};
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
export const HP_CRED_001 = {
|
|
189
|
+
attack: CRED_001_CASE,
|
|
190
|
+
scenario: CRED_001_SCENARIO,
|
|
191
|
+
handoffAdapter: new ForwardCredentialAdapter(),
|
|
192
|
+
createContext: createP0ReferenceContext,
|
|
193
|
+
};
|
|
194
|
+
export const HP_CRED_002 = {
|
|
195
|
+
attack: CRED_002_CASE,
|
|
196
|
+
scenario: CRED_002_SCENARIO,
|
|
197
|
+
handoffAdapter: new ForwardCredentialAdapter(),
|
|
198
|
+
createContext: credentialOnlyContext,
|
|
199
|
+
};
|
|
200
|
+
export const P0_CREDENTIAL_ATTACKS = [HP_CRED_001, HP_CRED_002];
|
|
201
|
+
export const P0_CREDENTIAL_BASELINE = {
|
|
202
|
+
fingerprint: P0_CREDENTIAL_FINGERPRINT,
|
|
203
|
+
expectedAudience: P0_MCP_AUDIENCE,
|
|
204
|
+
alternateAudience: P0_ALTERNATE_MCP_AUDIENCE,
|
|
205
|
+
};
|
|
206
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../src/attacks/p0/credentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { P0AttackPlan } from './types.js';
|
|
2
|
+
export declare const HP_ID_001: P0AttackPlan;
|
|
3
|
+
export declare const HP_ID_002: P0AttackPlan;
|
|
4
|
+
export declare const P0_IDENTITY_ATTACKS: readonly P0AttackPlan[];
|
|
5
|
+
export declare const P0_IDENTITY_BASELINE: {
|
|
6
|
+
readonly originalPrincipal: "user:alice";
|
|
7
|
+
readonly authorizedAgent: "agent:billing";
|
|
8
|
+
readonly unauthorizedAgent: "agent:support";
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/attacks/p0/identity.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA2R/C,eAAO,MAAM,SAAS,EAAE,YAQvB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,YAQvB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,SAAS,YAAY,EAA2B,CAAC;AAEnF,eAAO,MAAM,oBAAoB;;;;CAMvB,CAAC"}
|