aws / aws-sdk-js-v3

Modularized AWS SDK for JavaScript.
Apache License 2.0
2.95k stars 554 forks source link

systemClockOffset not applied to events sent over websocket connection #6217

Closed esauerbo closed 1 day ago

esauerbo commented 4 days ago

Checkboxes for prior research

Describe the bug

Manually setting the systemClockOffset allows me to successfully establish a websocket connection, but an InvalidSignatureException is returned once events are sent over the connection.

SDK version number

@aws-sdk/client-rekognitionstreamin@3.600.0

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

Chrome 126

Reproduction Steps

Reproduction branch: https://github.com/esauerbo/rekognition-sdk-repro/tree/clockSkew

  1. Checkout to the clockSkew branch
  2. npm install
  3. Get credentials and add to .env
  4. npm run dev
  5. Set system clock to one hour ahead (without changing time zone)
  6. Check network tab for start-face-liveness-session network request. Observe that connection is established successfully but after client sends event, server sends InvalidSignatureException Screenshot 2024-06-24 at 11 48 36 AM

Observed Behavior

Received error for invalid signature exception

Expected Behavior

systemClockOffset should be applied to events sent over websocket connection.

Possible Solution

This may be relevant, offset doesn't seem to be getting applied. https://github.com/aws/aws-sdk-js-v3/blob/f922dc18d7bd00bbc4c21f2e833e0faa4cf18ad3/packages/middleware-websocket/src/get-event-signing-stream.ts#L33

Additional Information/Context

No response

kuhe commented 3 days ago

related https://github.com/aws/aws-sdk-js-v3/pull/5015

kuhe commented 2 days ago

Due to the inability to read the date header in the upgrade response (https://github.com/aws/aws-sdk-js-v3/issues/6221),

to make use of the fix in #6227, the systemClockOffset must be supplied to the RekognitionStreaming client at initialization.

Example:

import { Rekognition } from '@aws-sdk/client-rekognition';
import { RekognitionStreaming } from '@aws-sdk/client-rekognitionstreaming';

const rekognition = new Rekognition({ ... });

// 1. make a request first, so that the client automatically corrects
// its config.systemClockOffset value if needed.
await rekognition.createFaceLivenessSession({ ... });

// 2. pass that value to the streaming client.
const rekognitionStreaming = new RekognitionStreaming({ 
  systemClockOffset: rekognition.config.systemClockOffset
});
thaddmt commented 2 days ago

@kuhe thanks for the recommendation but I believe that solution will not work for most rekognition consumers as it is recommended that the createFaceLivenessSession call be made in the developers backend where as the streaming client should be called from the customer's device.

I'm guessing in the example you posted above after calling the createFaceLivenessSession API the systemClockOffset value is set if a time difference is detected?

kuhe commented 1 day ago

This was released in https://github.com/aws/aws-sdk-js-v3/releases/tag/v3.605.0.

solution will not work for most rekognition consumers>

They need to know their system clock offset. We've established that the upgrade response headers are not an option.

I'm guessing in the example you posted above after calling the createFaceLivenessSession API the systemClockOffset value is set if a time difference is detected?

Yes.