Skip to content

fix(encryption): specify authTagLength on all AES-GCM cipher/decipher calls#3883

Merged
waleedlatif1 merged 47 commits intostagingfrom
waleedlatif1/gcm-cipher-authtag
Apr 1, 2026
Merged

fix(encryption): specify authTagLength on all AES-GCM cipher/decipher calls#3883
waleedlatif1 merged 47 commits intostagingfrom
waleedlatif1/gcm-cipher-authtag

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

@waleedlatif1 waleedlatif1 commented Apr 1, 2026

Summary

Affected Files

  • apps/sim/lib/api-key/crypto.ts
  • apps/sim/lib/core/security/encryption.ts
  • packages/db/scripts/migrate-block-api-keys-to-byok.ts

Test plan

  • Verify encryption/decryption round-trips still work (tag length matches on both sides)
  • Confirm no changes to stored ciphertext format

waleedlatif1 and others added 30 commits February 16, 2026 00:36
…stash, algolia tools; isolated-vm robustness improvements, tables backend (#3271)

* feat(tools): advanced fields for youtube, vercel; added cloudflare and dataverse tools (#3257)

* refactor(vercel): mark optional fields as advanced mode

Move optional/power-user fields behind the advanced toggle:
- List Deployments: project filter, target, state
- Create Deployment: project ID override, redeploy from, target
- List Projects: search
- Create/Update Project: framework, build/output/install commands
- Env Vars: variable type
- Webhooks: project IDs filter
- Checks: path, details URL
- Team Members: role filter
- All operations: team ID scope

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style(youtube): mark optional params as advanced mode

Hide pagination, sort order, and filter fields behind the advanced
toggle for a cleaner default UX across all YouTube operations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* added advanced fields for vercel and youtube, added cloudflare and dataverse block

* addded desc for dataverse

* add more tools

* ack comment

* more

* ops

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(tables): added tables (#2867)

* updates

* required

* trashy table viewer

* updates

* updates

* filtering ui

* updates

* updates

* updates

* one input mode

* format

* fix lints

* improved errors

* updates

* updates

* chages

* doc strings

* breaking down file

* update comments with ai

* updates

* comments

* changes

* revert

* updates

* dedupe

* updates

* updates

* updates

* refactoring

* renames & refactors

* refactoring

* updates

* undo

* update db

* wand

* updates

* fix comments

* fixes

* simplify comments

* u[dates

* renames

* better comments

* validation

* updates

* updates

* updates

* fix sorting

* fix appearnce

* updating prompt to make it user sort

* rm

* updates

* rename

* comments

* clean comments

* simplicifcaiton

* updates

* updates

* refactor

* reduced type confusion

* undo

* rename

* undo changes

* undo

* simplify

* updates

* updates

* revert

* updates

* db updates

* type fix

* fix

* fix error handling

* updates

* docs

* docs

* updates

* rename

* dedupe

* revert

* uncook

* updates

* fix

* fix

* fix

* fix

* prepare merge

* readd migrations

* add back missed code

* migrate enrichment logic to general abstraction

* address bugbot concerns

* adhere to size limits for tables

* remove conflicting migration

* add back migrations

* fix tables auth

* fix permissive auth

* fix lint

* reran migrations

* migrate to use tanstack query for all server state

* update table-selector

* update names

* added tables to permission groups, updated subblock types

---------

Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
Co-authored-by: waleed <walif6@gmail.com>

* fix(snapshot): changed insert to upsert when concurrent identical child workflows are running (#3259)

* fix(snapshot): changed insert to upsert when concurrent identical child workflows are running

* fixed ci tests failing

* fix(workflows): disallow duplicate workflow names at the same folder level (#3260)

* feat(tools): added redis, upstash, algolia, and revenuecat (#3261)

* feat(tools): added redis, upstash, algolia, and revenuecat

* ack comment

* feat(models): add gemini-3.1-pro-preview and update gemini-3-pro thinking levels (#3263)

* fix(audit-log): lazily resolve actor name/email when missing (#3262)

* fix(blocks): move type coercions from tools.config.tool to tools.config.params (#3264)

* fix(blocks): move type coercions from tools.config.tool to tools.config.params

Number() coercions in tools.config.tool ran at serialization time before
variable resolution, destroying dynamic references like <block.result.count>
by converting them to NaN/null. Moved all coercions to tools.config.params
which runs at execution time after variables are resolved.

Fixed in 15 blocks: exa, arxiv, sentry, incidentio, wikipedia, ahrefs,
posthog, elasticsearch, dropbox, hunter, lemlist, spotify, youtube, grafana,
parallel. Also added mode: 'advanced' to optional exa fields.

Closes #3258

* fix(blocks): address PR review — move remaining param mutations from tool() to params()

- Moved field mappings from tool() to params() in grafana, posthog,
  lemlist, spotify, dropbox (same dynamic reference bug)
- Fixed parallel.ts excerpts/full_content boolean logic
- Fixed parallel.ts search_queries empty case (must set undefined)
- Fixed elasticsearch.ts timeout not included when already ends with 's'
- Restored dropbox.ts tool() switch for proper default fallback

* fix(blocks): restore field renames to tool() for serialization-time validation

Field renames (e.g. personalApiKey→apiKey) must be in tool() because
validateRequiredFieldsBeforeExecution calls selectToolId()→tool() then
checks renamed field names on params. Only type coercions (Number(),
boolean) stay in params() to avoid destroying dynamic variable references.

* improvement(resolver): resovled empty sentinel to not pass through unexecuted valid refs to text inputs (#3266)

* fix(blocks): add required constraint for serviceDeskId in JSM block (#3268)

* fix(blocks): add required constraint for serviceDeskId in JSM block

* fix(blocks): rename custom field values to request field values in JSM create request

* fix(trigger): add isolated-vm support to trigger.dev container builds (#3269)

Scheduled workflow executions running in trigger.dev containers were
failing to spawn isolated-vm workers because the native module wasn't
available in the container. This caused loop condition evaluation to
silently fail and exit after one iteration.

- Add isolated-vm to build.external and additionalPackages in trigger config
- Include isolated-vm-worker.cjs via additionalFiles for child process spawning
- Add fallback path resolution for worker file in trigger.dev environment

* fix(tables): hide tables from sidebar and block registry (#3270)

* fix(tables): hide tables from sidebar and block registry

* fix(trigger): add isolated-vm support to trigger.dev container builds (#3269)

Scheduled workflow executions running in trigger.dev containers were
failing to spawn isolated-vm workers because the native module wasn't
available in the container. This caused loop condition evaluation to
silently fail and exit after one iteration.

- Add isolated-vm to build.external and additionalPackages in trigger config
- Include isolated-vm-worker.cjs via additionalFiles for child process spawning
- Add fallback path resolution for worker file in trigger.dev environment

* lint

* fix(trigger): update node version to align with main app (#3272)

* fix(build): fix corrupted sticky disk cache on blacksmith (#3273)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Lakee Sivaraya <71339072+lakeesiv@users.noreply.github.com>
Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
… fixes, removed retired models, hex integration
…ogle tasks and bigquery integrations, workflow lock
Sg312 and others added 14 commits March 24, 2026 04:06
v0.6.8: mothership tool loop
… improvements, copy logs, knowledgebase robustness
…, new gpt 5.4 models, fireworks provider support, launchdarkly, tailscale, extend integrations
Fixes missing authTagLength parameter in createDecipheriv calls using
AES-256-GCM mode. Without explicit tag length specification, the
application may be tricked into accepting shorter authentication tags,
potentially allowing ciphertext spoofing.

CWE-310: Cryptographic Issues (gcm-no-tag-length)
…tency

Complements #3881 by adding explicit authTagLength: 16 to the encrypt
side as well, ensuring both cipher and decipher specify the tag length.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Apr 1, 2026 5:35pm

Request Review

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 1, 2026

PR Summary

Medium Risk
Touches core encryption/decryption paths; while intended to be behavior-preserving, any mismatch could break decrypting previously stored secrets or migration output.

Overview
Ensures all AES-256-GCM operations explicitly use authTagLength: 16 on both createCipheriv and createDecipheriv for API key encryption, general secret encryption, and the BYOK migration script.

Also simplifies API-key ciphertext handling by requiring exactly three :-separated components (iv:encrypted:authTag) and reuses a cached ivHex, plus slightly hardens decryption error logging to handle non-Error exceptions.

Written by Cursor Bugbot for commit 276c281. Configure here.

@waleedlatif1 waleedlatif1 changed the title fix: specify authTagLength on all AES-GCM cipher/decipher calls fix(encryption): specify authTagLength on all AES-GCM cipher/decipher calls Apr 1, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 1, 2026

Greptile Summary

This PR adds explicit authTagLength: 16 to all createCipheriv calls across three files, complementing PR #3881 which added it to createDecipheriv calls. The change is a defense-in-depth improvement — Node.js AES-256-GCM already defaults to a 16-byte auth tag, so there is no behavioral change to ciphertext format or stored data.

Key changes:

  • apps/sim/lib/api-key/crypto.ts: Adds authTagLength: 16 to createCipheriv; refactors decryptApiKey to split the encrypted string once (avoiding a redundant .split(':') call), simplifies parse index access to direct parts[2]/parts[1], and narrows the catch error type from any to unknown.
  • apps/sim/lib/core/security/encryption.ts: Adds authTagLength: 16 to both createCipheriv and createDecipheriv; improves catch (error: any) to catch (error: unknown) with proper instanceof Error narrowing.
  • packages/db/scripts/migrate-block-api-keys-to-byok.ts: Adds authTagLength: 16 to both cipher and decipher calls in the standalone migration script, keeping it consistent with the app-level helpers.

All round-trips are unaffected. No migration or format change is required.

Confidence Score: 5/5

  • Safe to merge — changes are additive/explicit defaults with no behavioral or format impact.
  • All three files receive only the authTagLength: 16 option which matches Node.js's existing default for AES-GCM, so no encrypted data on disk is affected. The additional refactors (single split, direct index access, unknown error type) are demonstrably correct. The sole P2 comment flags a minor style inconsistency between decryptSecret and decryptApiKey parse patterns.
  • No files require special attention.

Important Files Changed

Filename Overview
apps/sim/lib/api-key/crypto.ts Adds authTagLength: 16 to createCipheriv; refactors decryptApiKey to split once, use direct index access, and narrows error type to unknown — all correct and safe.
apps/sim/lib/core/security/encryption.ts Adds authTagLength: 16 to createCipheriv and createDecipheriv; improves catch (error: any)catch (error: unknown) with proper type narrowing. decryptSecret parsing style not updated to match crypto.ts, but functionally identical.
packages/db/scripts/migrate-block-api-keys-to-byok.ts Adds authTagLength: 16 to both createCipheriv and createDecipheriv in the self-contained migration script, keeping it in sync with the app-level encryption helpers.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant encryptFn as encryptSecret / encryptApiKey
    participant Node as Node.js crypto
    participant decryptFn as decryptSecret / decryptApiKey

    Caller->>encryptFn: plaintext
    encryptFn->>Node: createCipheriv('aes-256-gcm', key, iv, {authTagLength: 16})
    Node-->>encryptFn: cipher
    encryptFn->>Node: cipher.update() + cipher.final()
    Node-->>encryptFn: ciphertext (hex)
    encryptFn->>Node: cipher.getAuthTag()
    Node-->>encryptFn: authTag (16 bytes)
    encryptFn-->>Caller: "ivHex:cipherHex:authTagHex"

    Caller->>decryptFn: "ivHex:cipherHex:authTagHex"
    decryptFn->>Node: createDecipheriv('aes-256-gcm', key, iv, {authTagLength: 16})
    Node-->>decryptFn: decipher
    decryptFn->>Node: decipher.setAuthTag(authTag)
    decryptFn->>Node: decipher.update() + decipher.final()
    Node-->>decryptFn: plaintext (GCM tag verified)
    decryptFn-->>Caller: plaintext
Loading

Reviews (2): Last reviewed commit: "refactor: clean up crypto modules" | Re-trigger Greptile

- Fix error: any → error: unknown with proper type guard in encryption.ts
- Eliminate duplicate iv.toString('hex') calls in both encrypt functions
- Remove redundant string split in decryptApiKey (was splitting twice)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

@waleedlatif1 waleedlatif1 changed the base branch from main to staging April 1, 2026 17:33
@waleedlatif1 waleedlatif1 merged commit 42fb434 into staging Apr 1, 2026
15 checks passed
@waleedlatif1 waleedlatif1 deleted the waleedlatif1/gcm-cipher-authtag branch April 1, 2026 17:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants