Skip to content

[High] Date/time review truncates multi-byte uint values in ui_712_format_datetime #993

@donjon-cerberus-sandbox

Description

@donjon-cerberus-sandbox

Location

  • File: src/features/sign_message_eip712/ui_logic.c
  • Lines: 708-719

Classification

Property Value
Severity High
Category Other
CWE CWE-CWE-451
OWASP A04:2021-Insecure Design
Confidence Confirmed
Likelihood Medium

Technical Description

The date/time formatter accepts any uint field selected by a trusted date-time filter, but it converts the raw value with u64_from_BE(data, length). u64_from_BE() only consumes the first 8 bytes of the supplied buffer. For EIP-712 uint256 timestamps, or for non-minimal encodings with attacker-added leading zero bytes, the device displays a truncated/smaller timestamp while the signing hash is computed from the full integer value. Because leading zero bytes do not change the final 32-byte EIP-712 integer encoding, a malicious host can keep the signed value valid while showing a much earlier date on-screen.

Vulnerable Code

static bool ui_712_format_datetime(const uint8_t *data,
                                   uint8_t length,
                                   const s_struct_712_field *field_ptr) {
    time_t timestamp;

    if ((length >= field_ptr->type_size) && ismaxint((uint8_t *) data, length)) {
        snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "Unlimited");
        return true;
    }
    timestamp = u64_from_BE(data, length);
    return time_format_to_utc(&timestamp, strings.tmp.tmp, sizeof(strings.tmp.tmp));
}

Impact

Network: a remote wallet-connected attacker can craft EIP-712 timestamp/deadline fields so the review screen shows an earlier or expired-looking date while the signed message contains a longer-lived deadline. This can trick the user into approving signatures that remain valid far longer than displayed.

Remediation

Only allow date/time formatting for integers that fit within 64 bits, and reject non-minimal encodings. Alternatively, normalize the value first by stripping leading zeros and then require the remaining length to be <= 8 before calling u64_from_BE().


Created by Cerberus Merlin

Metadata

Metadata

Assignees

No one assigned

    Labels

    highHigh severitysecuritySecurity finding

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions