SCRAM authentication fails on non-Node runtimes (Deno) in 7.2.0 — Uint8Array.toString() in authMessage

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Unknown
    • None
    • Affects Version/s: 7.2.0
    • Component/s: Authentication
    • 5
    • 3
    • Not Needed
    • None
    • Not Needed
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?
    • None
    • None
    • None
    • None
    • None
    • None

      Use Case

      As a developer using the MongoDB Node.js driver on Deno,
      I want SCRAM authentication to work after the Web Crypto migration in 7.2.0,
      So that I can connect to MongoDB Atlas without pinning to 7.1.0.

      User Experience

      SCRAM auth (both SHA-1 and SHA-256) fails with `MongoServerError: Authentication failed` (code 18) on Deno with mongodb 7.2.0. Same credentials work with 7.1.0 and with mongosh. Anyone using the driver on a non-Node runtime is blocked — the only workaround is pinning to 7.1.0.

      Dependencies

      Introduced by PR #4862 (NODE-7379), which moved SCRAM crypto from Node.js `crypto` to Web Crypto API. `clientFirstMessageBare` was changed from `Buffer.concat` to `ByteUtils.concat`, returning a `Uint8Array` instead of a `Buffer`.

      Risks/Unknowns

      This is standard JavaScript behavior, not a Deno bug. `Uint8Array.toString()` returns comma-separated byte values per spec. `Buffer.toString()` returns UTF-8 because Node overrides it. Any runtime where `ByteUtils.concat` returns a plain `Uint8Array` will hit this — Deno, likely Cloudflare Workers, possibly Bun.

      There may be other places in the NODE-7379 changes where `Uint8Array` values get implicitly stringified expecting UTF-8 output.

      Acceptance Criteria

      Implementation Requirements

      In `continueScramConversation` (lib/cmap/auth/scram.ts), the `authMessage` is built by joining an array:

      const authMessage = [
          clientFirstMessageBare(username, nonce),  // Uint8Array in 7.2.0
          payload.toString('utf8'),
          withoutProof
      ].join(',');
      

      `Array.join()` calls `.toString()` on each element. For `Buffer`, that's UTF-8 text: `"n=orders,r=..."`. For `Uint8Array`, that's comma-separated byte values: `"110,61,111,114,100,101,114,115,..."`. The SCRAM proof is computed against the wrong `authMessage`, so the server rejects it.

      Fix — decode the `Uint8Array` before joining:

      const authMessage = [
          new TextDecoder().decode(clientFirstMessageBare(username, nonce)),
          payload.toString('utf8'),
          withoutProof
      ].join(',');
      

      Confirmed by patching scram.js to log `authMessage` — the first segment was byte values instead of UTF-8 text.

      Testing Requirements

      • A test that verifies `authMessage` is a valid UTF-8 string when `clientFirstMessageBare` returns a `Uint8Array` (not a `Buffer`). Running SCRAM auth against a non-Node runtime in CI would catch this class of issue going forward.
      • Fix existing tests so that we aren't implicitly using Buffer in our tests (our bundler was targeting node instead of web)
      • Add a test to ensure that we actually don't have access to node-specific APIs that we have explicitly moved away from after filling the sandbox with the minimum required APIs

      Documentation Requirements

      • None — regression fix.

      Follow Up Requirements

      • File a ticket in the Runtime Dependencies epic to check other locations changed in NODE-7379 for implicit `.toString()` on `Uint8Array` values that were previously `Buffer`. The `xor` function was also rewritten and may have similar issues on non-Node runtimes.

            Assignee:
            Pavel Safronov
            Reporter:
            Jason Smith
            Sergey Zelenov
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: