aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.41k stars 2.12k forks source link

InvalidSignatureException when calling Lambda func from front end (using Cognito auth) #9787

Closed ffxsam closed 2 years ago

ffxsam commented 2 years ago

Before opening, please confirm:

JavaScript Framework

Vue

Amplify APIs

Authentication

Amplify Categories

No response

Environment information

``` # Put output below this line System: OS: macOS 11.6.4 CPU: (12) x64 Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz Memory: 2.19 GB / 64.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 14.19.1 - ~/Library/Caches/fnm_multishells/39177_1649343359988/bin/node Yarn: 3.0.2 - ~/Library/Caches/fnm_multishells/39177_1649343359988/bin/yarn npm: 6.14.16 - ~/Library/Caches/fnm_multishells/39177_1649343359988/bin/npm Watchman: 2022.03.21.00 - /usr/local/bin/watchman Browsers: Brave Browser: 91.1.26.74 Chrome: 100.0.4896.75 Firefox: 97.0.2 Safari: 15.3 npmPackages: @aws-sdk/client-cognito-identity-provider: ^3.58.0 => 3.58.0 @aws-sdk/client-evidently: ^3.58.0 => 3.58.0 @aws-sdk/client-lambda: ^3.58.0 => 3.58.0 @aws-sdk/client-s3: ^3.58.0 => 3.58.0 (3.6.1) @aws-sdk/lib-storage: ^3.58.0 => 3.58.0 @casl/ability: ^5.4.3 => 5.4.3 @casl/ability/extra: undefined () @casl/vue: ^1.2.3 => 1.2.3 @chargebee/chargebee-js-vue-wrapper: ^0.2.2 => 0.2.2 @sentry/browser: ^6.19.4 => 6.19.4 @sentry/cli: ^1.74.3 => 1.74.3 (1.73.0) @sentry/vue: ^6.19.4 => 6.19.4 @sentry/webpack-plugin: ^1.18.8 => 1.18.8 @types/canvas-confetti: ^1.4.2 => 1.4.2 @types/debug: ^4.1.7 => 4.1.7 @types/hls.js: ^1.0.0 => 1.0.0 @types/jest: ^24.9.1 => 24.9.1 @types/lodash.clonedeep: ^4 => 4.5.6 @types/lodash.debounce: ^4.0.6 => 4.0.6 @types/lodash.isequal: ^4 => 4.5.5 @types/lodash.throttle: ^4.1.6 => 4.1.6 @types/lodash.uniq: ^4 => 4.5.6 @types/nprogress: ^0.2.0 => 0.2.0 @types/safe-json-stringify: ^1.1.2 => 1.1.2 @types/sortablejs: ^1 => 1.10.7 @types/tinycolor2: ^1 => 1.4.3 @types/uuid: ^8.3.1 => 8.3.1 @types/validator: ^13.6.3 => 13.6.3 @types/yt-player: ^3.5.1 => 3.5.1 @types/zxcvbn: ^4.4.1 => 4.4.1 @typescript-eslint/eslint-plugin: ^4.33.0 => 4.33.0 @typescript-eslint/parser: ^4.33.0 => 4.33.0 @vue/cli-plugin-babel: ~4.5.15 => 4.5.15 @vue/cli-plugin-e2e-cypress: ~4.5.15 => 4.5.15 @vue/cli-plugin-eslint: ~4.5.15 => 4.5.15 @vue/cli-plugin-pwa: ~4.5.15 => 4.5.15 @vue/cli-plugin-router: ~4.5.15 => 4.5.15 @vue/cli-plugin-typescript: ~4.5.15 => 4.5.15 @vue/cli-plugin-unit-jest: ~4.5.15 => 4.5.15 @vue/cli-plugin-vuex: ~4.5.15 => 4.5.15 @vue/cli-service: ~4.5.15 => 4.5.15 @vue/eslint-config-standard: ^5.1.2 => 5.1.2 @vue/eslint-config-typescript: ^7.0.0 => 7.0.0 @vue/test-utils: ^1.3.0 => 1.3.0 apexcharts: ^3.35.0 => 3.35.0 aws-amplify: ^4.3.19 => 4.3.19 aws-sdk: ^2.1108.0 => 2.1108.0 axios: ^0.26.1 => 0.26.1 (0.21.4) camelcase-keys: ^7.0.2 => 7.0.2 (6.2.2) canvas-confetti: ^1.5.1 => 1.5.1 change-case: ^4.1.2 => 4.1.2 core-js: ^3.21.1 => 3.21.1 (3.12.1, 2.6.12, 3.20.2) date-fns: ^2.28.0 => 2.28.0 (1.30.1) date-fns-tz: ^1.3.3 => 1.3.3 debug: ^4.3.4 => 4.3.4 (4.3.2, 3.2.7, 2.6.9, 3.2.6) dev: 1.0.0 eslint: ^6.8.0 => 6.8.0 eslint-plugin-import: ^2.25.4 => 2.25.4 eslint-plugin-node: ^11.1.0 => 11.1.0 eslint-plugin-promise: ^4.3.1 => 4.3.1 eslint-plugin-standard: ^4.1.0 => 4.1.0 eslint-plugin-vue: ^6.2.2 => 6.2.2 example: 0.1.0 filesize: ^8.0.7 => 8.0.7 (3.6.1) friendly-challenge: ^0.9.1 => 0.9.1 graphql-tag: ^2.12.6 => 2.12.6 hls.js: ^1.1.5 => 1.1.5 (1.0.3) keycode: ^2.2.1 => 2.2.1 lint-staged: ^9.5.0 => 9.5.0 lodash.clonedeep: ^4.5.0 => 4.5.0 lodash.debounce: ^4.0.8 => 4.0.8 lodash.isequal: ^4.5.0 => 4.5.0 lodash.throttle: ^4.1.1 => 4.1.1 lodash.uniq: ^4.5.0 => 4.5.0 logrocket: ^2.2.1 => 2.2.1 logrocket-vuex: 0.0.3 => 0.0.3 nprogress: ^0.2.0 => 0.2.0 peaks.js: 0.27.0 plyr: ^3.6.12 => 3.6.12 prettier: ^2.6.2 => 2.6.2 (1.19.1) quill-paste-smart: ^1.4.10 => 1.4.10 register-service-worker: ^1.7.2 => 1.7.2 safe-json-stringify: ^1.2.0 => 1.2.0 sass: 1.32.0 => 1.32.0 sass-loader: ^8.0.2 => 8.0.2 snakecase-keys: ^5.4.0 => 5.4.0 sortablejs: ^1.15.0 => 1.15.0 tinycolor2: ^1.4.2 => 1.4.2 typescript: ~4.6.2 => 4.6.2 userpilot: ^1.2.5 => 1.2.5 uuid: ^8.3.2 => 8.3.2 (3.4.0, 3.3.2) validator: ^13.7.0 => 13.7.0 vue: ^2.6.14 => 2.6.14 (2.6.12) vue-apexcharts: ^1.6.2 => 1.6.2 vue-chartjs: ^3.5.1 => 3.5.1 vue-cli-plugin-vuetify: ~2.4.8 => 2.4.8 vue-linkify: ^1.0.1 => 1.0.1 vue-meta: ^2.4.0 => 2.4.0 vue-quill-editor: ^3.0.6 => 3.0.6 vue-router: ^3.5.3 => 3.5.3 vue-smooth-dnd: ^0.8.1 => 0.8.1 vue-template-compiler: ^2.6.14 => 2.6.14 vuetify: ^2.6.4 => 2.6.4 vuetify-loader: ^1.7.3 => 1.7.3 vuex: ^3.6.2 => 3.6.2 vuex-persistedstate: ^4.1.0 => 4.1.0 yt-player: ^3.5.0 => 3.5.0 zxcvbn: ^4.4.2 => 4.4.2 npmGlobalPackages: @vue/cli: 5.0.4 corepack: 0.10.0 diff-so-fancy: 1.4.3 npm: 6.14.16 serverless: 2.72.3 yarn: 1.22.18 ```

Describe the bug

Sometimes our customers get an error because a Lambda call was unable to complete successfully. We're seeing an InvalidSignatureException with the following message:

The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

I confirmed that the user's computer clock isn't off, which is sometimes the cause of this error, at least with S3 uploads. The strange part is, that the user had no problem invoking the Lambda function at one point, but then 20 minutes later, the same calls failed. The only thing that stood out to me was that the later invocations that failed had a payload that included accented characters (é), though, in my own testing, that's never been an issue. I'm even stripping non-printable characters just to be safe:

export function removeNonPrintableChars(text: string): string {
  return text.replace(/[\x00-\x08\x0e-\x1f\x7f\x8d-\x9f]/g, '');
}

Expected behavior

I would expect Amplify to generate a correct signature.

Reproduction steps

Sporadic error, can't replicate at the moment.

Code Snippet

const filename = removeNonPrintableChars(file.name);
const params = {
  FunctionName: process.env.VUE_APP_PROCESSOR_LAMBDA_NAME,
  Payload: JSON.stringify({
    userId: rootState.auth.user.userId,
    id: mediaId,
    replace: !!replaceMediaId,
    fileId,
    fileCategory: fileType.category,
    bucket: process.env.VUE_APP_UPLOAD_BUCKET,
    key: destKey,
    duration,
    originalFilename: filename,
  }),
} as unknown as InvokeCommandInput;

const data = await lambda.invoke(params);

Log output

Request headers:

{
  "amz-sdk-invocation-id": "0e5a97e8-f0fd-44b6-901e-6ac7b41c2a4a",
  "amz-sdk-request": "attempt=2; max=3",
  "authorization": "AWS4-HMAC-SHA256 Credential=xx/20220407/us-east-1/lambda/aws4_request, SignedHeaders=amz-sdk-invocation-id;amz-sdk-request;content-length;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent, Signature=xx",
  "content-type": "application/octet-stream",
  "x-amz-content-sha256": "2785a35474b8ce41154eb986e77e3ddc80cda05cdcb055cde85fec8967c145c0",
  "x-amz-date": "20220407T003409Z",
  "x-amz-security-token": "xx",
  "x-amz-user-agent": "aws-sdk-js/3.55.0 os/macOS/10.15.7 lang/js md/browser/Safari_14.1.2 api/lambda/3.55.0"
}

Request body:

{
  "userId": "13cef582-65ee-4188-9233-9eb00d8092bc",
  "id": "0f35725d-c035-4a31-b8d5-405e97e4c4a8",
  "replace": false,
  "fileId": "081fa32d-b4d6-4bbc-8809-02c62761c7c4",
  "fileCategory": "audio",
  "bucket": "xx",
  "key": "staging/audio/081fa32d-b4d6-4bbc-8809-02c62761c7c4.mp3",
  "duration": 49.728,
  "originalFilename": "#00 Générique début MIX DEF ALTERNATE.mp3"
}

Response headers:

{
  "content-length": "192",
  "content-type": "application/json",
  "date": "Thu, 07 Apr 2022 00:34:09 GMT",
  "x-amzn-errortype": "InvalidSignatureException",
  "x-amzn-requestid": "b6e0db72-0eee-4cda-aeb5-1446fc29019e"
}

Response body:

{
  "message": "The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."
}

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

chrisbonifacio commented 2 years ago

Hi @ffxsam 👋 thanks for raising this issue. Wanted to follow up and ask if you've been able to consistently reproduce this yet or still experiencing the issue and have gathered any more information that might help us reproduce this?

ffxsam commented 2 years ago

Hey @chrisbonifacio! It might've been possible that the user was using an older, cached version of our application. I'm not entirely sure. But I decided to play it safe and just base64-encode the originalFilename property anyway, and this hasn't been an issue since.

chrisbonifacio commented 2 years ago

Glad to hear it hasn't been an issue!

Thanks for letting us know what worked for you in case anyone else runs into this issue intermittently as well.

github-actions[bot] commented 1 year ago

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server amplify-help forum.