-
Notifications
You must be signed in to change notification settings - Fork 542
Open
Labels
Description
strkey.DecodeSignedPayload() panics when given a P-address with a payload shorter than 32 bytes. The function slices raw[:32] without checking length first.
Root Cause
strkey/signed_payload.go:DecodeSignedPayload() assumes payload is ≥ 32 bytes:
func DecodeSignedPayload(address string) (*SignedPayload, error) {
raw, err := Decode(VersionByteSignedPayload, address)
if err != nil {
return nil, errors.New("invalid signed payload")
}
const signerLen = 32
rawSigner, raw := raw[:signerLen], raw[signerLen:] // PANIC if len(raw) < 32
// ...
}Decode() only validates version byte and CRC — it returns payloads of any length.
Compare with DecodeMuxedAccount() which correctly validates: if len(raw) != 40 { return error }
Impact
- Affects apps calling DecodeSignedPayload() directly on untrusted input
- Also reachable via xdr.SignerKey.SetAddress() with P-addresses
Note: Horizon/RPC are not affected — Horizon never callsDecodeSignedPayload()
Fix
func DecodeSignedPayload(address string) (*SignedPayload, error) {
raw, err := Decode(VersionByteSignedPayload, address)
if err != nil {
return nil, errors.New("invalid signed payload")
}
const signerLen = 32
if len(raw) < signerLen {
return nil, errors.Errorf("signed payload too short: %d bytes", len(raw))
}
rawSigner, raw := raw[:signerLen], raw[signerLen:]
// ...
}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
To Do