Skip to content

pallet-signet: respond/respond_error/respond_bidirectional are unauthenticated and unvalidated #1494

Description

@mrq1911

Summary

The three response extrinsics in pallet-signetrespond (call_index 4), respond_error (5), and respond_bidirectional (6) — perform no authorization, no pause check, and no validation. Each only calls ensure_signed(origin) and then re-emits the caller's raw input as an event. Any signed account can emit arbitrary signing responses for any request_id.

Surfaced while adding integration-test coverage for the pallet (integration-tests/src/signet.rs, PR #1490).

Details

pallets/signet/src/lib.rs (lines ~391–449):

  • No authority gate. sign/sign_bidirectional, set_config, pause/unpause, and withdraw_funds are gated (signed requester or UpdateOrigin). The respond* calls are gated only by ensure_signed — there is no check that the responder is an authorized MPC signer / relayer.
  • No pause check. sign and sign_bidirectional both ensure!(!config.paused, Error::Paused). The respond* calls have no such check, so responses keep flowing even while the pallet is paused.
  • No request validation. request_id is not checked against any stored pending request — arbitrary ids are accepted.
  • No signature verification. The submitted Signature / serialized_output are emitted verbatim; nothing verifies they are well-formed or authentic.

respond also emits request_ids.len() events after only checking request_ids.len() == signatures.len() — unbounded-ish work is bounded by MAX_BATCH_SIZE, but it is callable by anyone.

Impact

Depends on the off-chain trust model. If relayers, the MPC network, indexers, or dApps treat SignatureResponded / SignatureError / RespondBidirectionalEvent as authoritative:

  • Response spoofing — anyone can emit a RespondBidirectionalEvent with a forged serialized_output/signature for a real request_id.
  • Griefing — anyone can emit SignatureError for a live request_id, or flood spurious SignatureResponded events.

If consumers already independently verify signatures against the expected MPC key off-chain, on-chain impact is limited to event noise — but the pallet then provides no on-chain guarantee about who responded.

Suggested direction

  • Gate respond* on an authorized-responder origin/set (or UpdateOrigin), and/or verify the submitted signature against the configured signing key.
  • Apply the same paused check used by sign/sign_bidirectional.
  • Consider validating request_id against stored pending requests.

Notes

  • Not fixed here; PR test: integration coverage for untested extrinsics across 8 pallets #1490 only adds tests that assert current behavior (permissionless event emission) so a future fix has a baseline.
  • build_evm_tx's error paths (DataTooLong, InvalidAddress, InvalidGasPrice) are in a public helper, not an extrinsic, so they aren't reachable via dispatch and aren't covered.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions