From e8eaa0dc59a6d9137b1314704a186a966e30b46d Mon Sep 17 00:00:00 2001 From: chasprowebdev Date: Mon, 11 May 2026 14:38:25 -0400 Subject: [PATCH 1/3] fix(api): prevent stack overflow during base64 file parsing --- .../evidence-forms/evidence-forms.service.ts | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/apps/api/src/evidence-forms/evidence-forms.service.ts b/apps/api/src/evidence-forms/evidence-forms.service.ts index f8abc214d5..38a3c8839f 100644 --- a/apps/api/src/evidence-forms/evidence-forms.service.ts +++ b/apps/api/src/evidence-forms/evidence-forms.service.ts @@ -196,19 +196,17 @@ export class EvidenceFormsService { ); } - const base64Pattern = /^[A-Za-z0-9+/]+={0,2}$/; - if (!base64Pattern.test(normalized)) { - throw new BadRequestException( - 'Invalid file data. Expected base64 string.', - ); - } + try { + const fileBuffer = Buffer.from(normalized, 'base64'); - const fileBuffer = Buffer.from(normalized, 'base64'); - if (!fileBuffer.length) { - throw new BadRequestException('File cannot be empty'); - } + if (!fileBuffer.length) { + throw new BadRequestException('File cannot be empty.'); + } - return fileBuffer; + return fileBuffer; + } catch { + throw new BadRequestException('Invalid file data. Expected base64 string.'); + } } /** From 35092d71b59b5cb7d47453fc0f498237a2c1dec0 Mon Sep 17 00:00:00 2001 From: chasprowebdev Date: Mon, 11 May 2026 15:31:58 -0400 Subject: [PATCH 2/3] fix(app): use re-encoding check for strict base64 validation --- .../evidence-forms/evidence-forms.service.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/api/src/evidence-forms/evidence-forms.service.ts b/apps/api/src/evidence-forms/evidence-forms.service.ts index 38a3c8839f..b1589ed906 100644 --- a/apps/api/src/evidence-forms/evidence-forms.service.ts +++ b/apps/api/src/evidence-forms/evidence-forms.service.ts @@ -196,17 +196,19 @@ export class EvidenceFormsService { ); } - try { - const fileBuffer = Buffer.from(normalized, 'base64'); + const fileBuffer = Buffer.from(normalized, 'base64'); - if (!fileBuffer.length) { - throw new BadRequestException('File cannot be empty.'); - } + if (fileBuffer.toString('base64') !== normalized) { + throw new BadRequestException( + 'Invalid file data. Expected base64 string.', + ); + } - return fileBuffer; - } catch { - throw new BadRequestException('Invalid file data. Expected base64 string.'); + if (!fileBuffer.length) { + throw new BadRequestException('File cannot be empty.'); } + + return fileBuffer; } /** From cce868ec24e3ec9ca22b61ddf75c27ed27310968 Mon Sep 17 00:00:00 2001 From: Tofik Hasanov Date: Mon, 11 May 2026 15:43:44 -0400 Subject: [PATCH 3/3] fix(cloud-security): ignore unused govcloud session token Co-authored-by: Cursor --- apps/api/.env.example | 3 ++- apps/api/src/cloud-security/aws-partition.utils.spec.ts | 3 +-- apps/api/src/cloud-security/aws-partition.utils.ts | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/api/.env.example b/apps/api/.env.example index fedfeaf98a..e2fea0ab10 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -58,4 +58,5 @@ SECURITY_HUB_ROLE_ASSUMER_ARN= SECURITY_HUB_GOVCLOUD_ROLE_ASSUMER_ARN= SECURITY_HUB_GOVCLOUD_ACCESS_KEY_ID= SECURITY_HUB_GOVCLOUD_SECRET_ACCESS_KEY= -SECURITY_HUB_GOVCLOUD_SESSION_TOKEN= +# Optional: only set when using temporary GovCloud credentials. Leave unset for long-lived IAM user keys. +# SECURITY_HUB_GOVCLOUD_SESSION_TOKEN= diff --git a/apps/api/src/cloud-security/aws-partition.utils.spec.ts b/apps/api/src/cloud-security/aws-partition.utils.spec.ts index 5f9f313092..b6dadf07ea 100644 --- a/apps/api/src/cloud-security/aws-partition.utils.spec.ts +++ b/apps/api/src/cloud-security/aws-partition.utils.spec.ts @@ -57,12 +57,11 @@ describe('aws partition utils', () => { it('uses explicit GovCloud base credentials when configured', () => { process.env.SECURITY_HUB_GOVCLOUD_ACCESS_KEY_ID = 'AKIAGOV'; process.env.SECURITY_HUB_GOVCLOUD_SECRET_ACCESS_KEY = 'secret'; - process.env.SECURITY_HUB_GOVCLOUD_SESSION_TOKEN = 'token'; + process.env.SECURITY_HUB_GOVCLOUD_SESSION_TOKEN = 'placeholder'; expect(getAwsBaseCredentials('aws-us-gov')).toEqual({ accessKeyId: 'AKIAGOV', secretAccessKey: 'secret', - sessionToken: 'token', }); expect(getAwsBaseCredentials('aws')).toBeUndefined(); diff --git a/apps/api/src/cloud-security/aws-partition.utils.ts b/apps/api/src/cloud-security/aws-partition.utils.ts index ce0596b0c0..3c30ad808e 100644 --- a/apps/api/src/cloud-security/aws-partition.utils.ts +++ b/apps/api/src/cloud-security/aws-partition.utils.ts @@ -41,7 +41,6 @@ export function getAwsBaseCredentials( return { accessKeyId, secretAccessKey, - sessionToken: process.env.SECURITY_HUB_GOVCLOUD_SESSION_TOKEN, }; }