paritytech / paritytech/triangle-js-sdks
Account methods expose cross-product data without JIT permission gating
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 3
- Forks
- 1
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 8
Description
Summary
host_account_get, host_account_get_alias, and host_account_create_proof accept a caller-supplied ProductAccountId (a (DotNsIdentifier, DerivationIndex) tuple) but are not behind any JIT permission check. A malicious product can invoke these methods with another product's DotNsIdentifier to obtain account public keys, contextual aliases, and ring VRF proofs that belong to a different product's domain — without user awareness or consent.
Affected Methods
| Method | Input | Returns | Risk |
|---|---|---|---|
host_account_get(ProductAccountId) |
(DotNsIdentifier, DerivationIndex) |
Account { publicKey, name } |
Leaks the user's derived public key for an arbitrary product domain |
host_account_get_alias(ProductAccountId) |
(DotNsIdentifier, DerivationIndex) |
ContextualAlias { context, alias } |
Leaks the user's ring VRF alias scoped to an arbitrary product domain |
host_account_create_proof(ProductAccountId, RingLocation, message) |
(DotNsIdentifier, DerivationIndex) + ring + message |
RingVrfProof |
Generates a valid proof on behalf of the user under an arbitrary product domain |
Current Implementation
In host-container, all three are created as plain makeNotImplementedSlot entries with no permission gating:
// packages/host-container/src/createContainer.ts:230-248
const handleAccountGetSlot = makeNotImplementedSlot(
'host_account_get',
() => new RequestCredentialsErr.Unknown({ reason: NOT_IMPLEMENTED }),
);
const handleAccountGetAliasSlot = makeNotImplementedSlot(
'host_account_get_alias',
() => new RequestCredentialsErr.Unknown({ reason: NOT_IMPLEMENTED }),
);
const handleAccountCreateProofSlot = makeNotImplementedSlot(
'host_account_create_proof',
() => new CreateProofErr.Unknown({ reason: NOT_IMPLEMENTED }),
);
Compare with remote_statement_store_submit and remote_preimage_submit, which use makePermissionGatedRequestSlot to enforce RemotePermission checks before the handler is called.
Attack Scenario
- Product A (e.g.
"malicious.dot") is loaded in the host. - Product A calls
host_account_get(["legitimate-product.dot", 0])— using product B's domain. - The host returns the user's derived public key for product B's domain without prompting the user.
- Product A now knows the user's public key in product B's context, enabling cross-product tracking/correlation.
- Similarly,
host_account_get_aliasleaks the user's contextual alias, andhost_account_create_proofallows generating proofs under another product's identity.
Suggested Mitigation
Options to consider (not mutually exclusive):
- Domain scoping at the container level: The host container should enforce that
DotNsIdentifierin the request matches the calling product's registered identity. Requests for other domains should be rejected. - JIT permission prompt: If cross-domain access is a legitimate use case, gate these methods behind a JIT user approval prompt (similar to signing methods returning
PermissionDenied/Rejectedon denial). - Spec update: The protocol spec (
docs/design/host-api-protocol.md) should document the expected host behavior — whether the host MUST restrictProductAccountIdto the calling product's own domain or MUST prompt for cross-domain access.
References
- Protocol spec:
docs/design/host-api-protocol.md(Accounts section, line ~630) - Container implementation:
packages/host-container/src/createContainer.ts(lines 230-248, 471-485) - Codec definitions:
packages/host-api/src/protocol/v1/accounts.ts
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/host-container/src/createContainer.ts, comparing the affected account slots with remote_statement_store_submit and remote_preimage_submit, then read the Accounts section of docs/design/host-api-protocol.md and the definitions in packages/host-api/src/protocol/v1/accounts.ts. The work is complete when the intended cross-domain policy is decided, enforced for all three methods, and documented in the protocol spec.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, authorization, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100