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:
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.
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:However, it does not include:
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
SignTxMessageon the NATS/message bus, they may be able to changederivation_pathwithout invalidating theinitiator 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 excludesderivation_path.Expected behavior:
derivation_pathshould be included in the canonical signed payload forSignTxMessage.Raw().Suggested fix:
Include
DerivationPathin the signed payload, for example:If backwards compatibility is required, a versioned signing payload may be safer.
Affected version tested:
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.