Skip to content

Consider not truncating lengths and instead [EnforceRange]? #429

@ChALkeR

Description

@ChALkeR

E.g. in deriveBits (but other places use blind conversion too) :

Promise<ArrayBuffer> deriveBits(
AlgorithmIdentifier algorithm,
CryptoKey baseKey,
optional unsigned long? length = null
);

webcrypto/spec/Overview.html

Lines 1289 to 1293 in 9d98db7

Promise&lt;ArrayBuffer> deriveBits(
AlgorithmIdentifier algorithm,
CryptoKey baseKey,
optional unsigned long? length = null
);

Here, length is unsigned long on the API level, and thus passing any non-nullish arg to it converts that arg to unsigned long.

More specifically, currently:

length = 2**32 + 8 is allowed and returns 1 byte

> await crypto.subtle.deriveBits({ name: 'PBKDF2', hash: 'SHA-256', iterations: 1, salt: Uint8Array.of(1) }, await crypto.subtle.importKey('raw', Uint8Array.of(1), 'PBKDF2', false, ['deriveBits']), 2**32 + 8)
ArrayBuffer(1)

length = -8 is allowed and returns 536870911 bytes

> await crypto.subtle.deriveBits({ name: 'PBKDF2', hash: 'SHA-256', iterations: 1, salt: Uint8Array.of(1) }, await crypto.subtle.importKey('raw', Uint8Array.of(1), 'PBKDF2', false, ['deriveBits']), -8)
ArrayBuffer(536870911)

Also length = NaN is allowed and returns an empty ArrayBuffer.

I would really have just preferred an error in both cases

Validation exists, but after conversion:

  • 0 returns 0 bytes.
  • 1 throws
  • -9 throws
  • -8 returns 536870911 bytes
  • undefined throws
  • null throws
  • NaN reuturns 0 bytes
  • Infinity returns 0 bytes
  • 25769803800 returns 3 bytes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    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