Skip to content

Potential security issue: SignTxMessage signature does not bind derivation_path #162

Description

@TimurZur

Hi Fystack team,

I found a potential security issue in Mpcium v0.3.5.

In pkg/types/initiator_msg.go, SignTxMessage.Raw() builds the canonical payload that is signed by the event initiator. The payload includes:

  • key_type
  • wallet_id
  • network_internal_code
  • tx_id
  • tx

However, it does not include:

  • derivation_path

This means the initiator signature authenticates the transaction digest and wallet id, but does not cryptographically bind the HD derivation path used for signing.

Impact:

If an attacker is able to modify or republish a signed SignTxMessage on the NATS/message bus, they may be able to change derivation_path without invalidating the
initiator signature. The MPC nodes could then sign the same transaction digest with a different derived child key than the one intended by the client/coordinator.

In many blockchain cases this may produce an invalid transaction signature, but it is still a security boundary issue: the field that selects the signing child key should be
covered by the authenticated message.

This may also affect authorizer signatures, because ComposeAuthorizerRaw() appears to sign the initiator raw payload/signature, and the initiator raw payload also excludes
derivation_path.

Expected behavior:

derivation_path should be included in the canonical signed payload for SignTxMessage.Raw().

Suggested fix:

Include DerivationPath in the signed payload, for example:

payload := struct {
    KeyType             KeyType  `json:"key_type"`
    WalletID            string   `json:"wallet_id"`
    NetworkInternalCode string   `json:"network_internal_code"`
    TxID                string   `json:"tx_id"`
    Tx                  []byte   `json:"tx"`
    DerivationPath      []uint32 `json:"derivation_path"`
}{
    KeyType:             m.KeyType,
    WalletID:            m.WalletID,
    NetworkInternalCode: m.NetworkInternalCode,
    TxID:                m.TxID,
    Tx:                  m.Tx,
    DerivationPath:      m.DerivationPath,
}

If backwards compatibility is required, a versioned signing payload may be safer.

Affected version tested:

  • github.com/fystack/mpcium v0.3.5

I have not tested this against a production deployment. This report is based on source-code review of the message canonicalization and signature verification boundary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions