mirror of
https://github.com/googleapis/genai-toolbox.git
synced 2026-01-09 15:38:08 -05:00
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [langchain](https://redirect.github.com/langchain-ai/langchainjs/tree/main/libs/langchain/) ([source](https://redirect.github.com/langchain-ai/langchainjs)) | [`1.0.2` → `1.2.3`](https://renovatebot.com/diffs/npm/langchain/1.0.2/1.2.3) |  |  | ### GitHub Vulnerability Alerts #### [CVE-2025-68665](https://redirect.github.com/langchain-ai/langchainjs/security/advisories/GHSA-r399-636x-v7f6) ## Context A serialization injection vulnerability exists in LangChain JS's `toJSON()` method (and subsequently when string-ifying objects using `JSON.stringify()`. The method did not escape objects with `'lc'` keys when serializing free-form data in kwargs. The `'lc'` key is used internally by LangChain to mark serialized objects. When user-controlled data contains this key structure, it is treated as a legitimate LangChain object during deserialization rather than plain user data. ### Attack surface The core vulnerability was in `Serializable.toJSON()`: this method failed to escape user-controlled objects containing `'lc'` keys within kwargs (e.g., `additional_kwargs`, `metadata`, `response_metadata`). When this unescaped data was later deserialized via `load()`, the injected structures were treated as legitimate LangChain objects rather than plain user data. This escaping bug enabled several attack vectors: 1. **Injection via user data**: Malicious LangChain object structures could be injected through user-controlled fields like `metadata`, `additional_kwargs`, or `response_metadata` 2. **Secret extraction**: Injected secret structures could extract environment variables when `secretsFromEnv` was enabled (which had no explicit default, effectively defaulting to `true` behavior) 3. **Class instantiation via import maps**: Injected constructor structures could instantiate any class available in the provided import maps with attacker-controlled parameters **Note on import maps:** Classes must be explicitly included in import maps to be instantiatable. The core import map includes standard types (messages, prompts, documents), and users can extend this via `importMap` and `optionalImportsMap` options. This architecture naturally limits the attack surface—an `allowedObjects` parameter is not necessary because users control which classes are available through the import maps they provide. **Security hardening:** This patch fixes the escaping bug in `toJSON()` and introduces new restrictive defaults in `load()`: `secretsFromEnv` now explicitly defaults to `false`, and a `maxDepth` parameter protects against DoS via deeply nested structures. JSDoc security warnings have been added to all import map options. ## Who is affected? Applications are vulnerable if they: 1. **Serialize untrusted data via `JSON.stringify()` on Serializable objects, then deserialize with `load()`** — Trusting your own serialization output makes you vulnerable if user-controlled data (e.g., from LLM responses, metadata fields, or user inputs) contains `'lc'` key structures. 2. **Deserialize untrusted data with `load()`** — Directly deserializing untrusted data that may contain injected `'lc'` structures. 3. **Use LangGraph checkpoints** — Checkpoint serialization/deserialization paths may be affected. The most common attack vector is through **LLM response fields** like `additional_kwargs` or `response_metadata`, which can be controlled via prompt injection and then serialized/deserialized in streaming operations. ## Impact Attackers who control serialized data can extract environment variable secrets by injecting `{"lc": 1, "type": "secret", "id": ["ENV_VAR"]}` to load environment variables during deserialization (when `secretsFromEnv: true`). They can also instantiate classes with controlled parameters by injecting constructor structures to instantiate any class within the provided import maps with attacker-controlled parameters, potentially triggering side effects such as network calls or file operations. Key severity factors: - Affects the serialization path—applications trusting their own serialization output are vulnerable - Enables secret extraction when combined with `secretsFromEnv: true` - LLM responses in `additional_kwargs` can be controlled via prompt injection ## Exploit example ```typescript import { load } from "@​langchain/core/load"; // Attacker injects secret structure into user-controlled data const attackerPayload = JSON.stringify({ user_data: { lc: 1, type: "secret", id: ["OPENAI_API_KEY"], }, }); process.env.OPENAI_API_KEY = "sk-secret-key-12345"; // With secretsFromEnv: true, the secret is extracted const deserialized = await load(attackerPayload, { secretsFromEnv: true }); console.log(deserialized.user_data); // "sk-secret-key-12345" - SECRET LEAKED! ``` ## Security hardening changes This patch introduces the following changes to `load()`: 1. **`secretsFromEnv` default changed to `false`**: Disables automatic secret loading from environment variables. Secrets not found in `secretsMap` now throw an error instead of being loaded from `process.env`. This fail-safe behavior ensures missing secrets are caught immediately rather than silently continuing with `null`. 2. **New `maxDepth` parameter** (defaults to `50`): Protects against denial-of-service attacks via deeply nested JSON structures that could cause stack overflow. 3. **Escape mechanism in `toJSON()`**: User-controlled objects containing `'lc'` keys are now wrapped in `{"__lc_escaped__": {...}}` during serialization and unwrapped as plain data during deserialization. 4. **JSDoc security warnings**: All import map options (`importMap`, `optionalImportsMap`, `optionalImportEntrypoints`) now include security warnings about never populating them from user input. ## Migration guide ### No changes needed for most users If you're deserializing standard LangChain types (messages, documents, prompts) using the core import map, your code will work without changes: ```typescript import { load } from "@​langchain/core/load"; // Works with default settings const obj = await load(serializedData); ``` ### For secrets from environment `secretsFromEnv` now defaults to `false`, and missing secrets throw an error. If you need to load secrets: ```typescript import { load } from "@​langchain/core/load"; // Provide secrets explicitly (recommended) const obj = await load(serializedData, { secretsMap: { OPENAI_API_KEY: process.env.OPENAI_API_KEY }, }); // Or explicitly opt-in to load from env (only use with trusted data) const obj = await load(serializedData, { secretsFromEnv: true }); ``` > **Warning:** Only enable `secretsFromEnv` if you trust the serialized data. Untrusted data could extract any environment variable. > **Note:** If a secret reference is encountered but not found in `secretsMap` (and `secretsFromEnv` is `false` or the secret is not in the environment), an error is thrown. This fail-safe behavior ensures you're aware of missing secrets rather than silently receiving `null` values. ### For deeply nested structures If you have legitimate deeply nested data that exceeds the default depth limit of 50: ```typescript import { load } from "@​langchain/core/load"; const obj = await load(serializedData, { maxDepth: 100 }); ``` ### For custom import maps If you provide custom import maps, ensure they only contain trusted modules: ```typescript import { load } from "@​langchain/core/load"; import * as myModule from "./my-trusted-module"; // GOOD - explicitly include only trusted modules const obj = await load(serializedData, { importMap: { my_module: myModule }, }); // BAD - never populate from user input const obj = await load(serializedData, { importMap: userProvidedImports, // DANGEROUS! }); ``` --- ### Release Notes <details> <summary>langchain-ai/langchainjs (langchain)</summary> ### [`v1.2.3`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/%40langchain/anthropic%401.2.3) ##### Patch Changes - Updated dependencies \[[`0bade90`](0bade90ed4), [`6c40d00`](6c40d00e92)]: - [@​langchain/core](https://redirect.github.com/langchain/core)@​1.1.4 ### [`v1.2.2`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/%40langchain/anthropic%401.2.2) ##### Patch Changes - [#​9520](https://redirect.github.com/langchain-ai/langchainjs/pull/9520) [`cc022b0`](cc022b0aab) Thanks [@​yukukotani](https://redirect.github.com/yukukotani)! - Includes cache creation/read tokens in input\_tokens of usage metadata - Updated dependencies \[[`bd2c46e`](bd2c46e09e), [`487378b`](487378bf14), [`138e7fb`](138e7fb628)]: - [@​langchain/core](https://redirect.github.com/langchain/core)@​1.1.3 ### [`v1.2.1`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/%40langchain/anthropic%401.2.1) [Compare Source](https://redirect.github.com/langchain-ai/langchainjs/compare/langchain@1.2.0...langchain@1.2.1) ##### Patch Changes - Updated dependencies \[[`833f578`](833f57834d)]: - [@​langchain/core](https://redirect.github.com/langchain/core)@​1.1.2 ### [`v1.2.0`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/langchain%401.2.0) [Compare Source](https://redirect.github.com/langchain-ai/langchainjs/compare/langchain@1.1.6...langchain@1.2.0) ##### Minor Changes - [#​9651](https://redirect.github.com/langchain-ai/langchainjs/pull/9651) [`348c37c`](348c37c01a) Thanks [@​christian-bromann](https://redirect.github.com/christian-bromann)! - feat(langchain): allow to set strict tag manually in providerStrategy [#​9578](https://redirect.github.com/langchain-ai/langchainjs/issues/9578) ### [`v1.1.6`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/langchain%401.1.6) [Compare Source](https://redirect.github.com/langchain-ai/langchainjs/compare/langchain@1.1.5...langchain@1.1.6) ##### Patch Changes - [#​9586](https://redirect.github.com/langchain-ai/langchainjs/pull/9586) [`bc8e90f`](bc8e90f4f7) Thanks [@​hntrl](https://redirect.github.com/hntrl)! - patch prompts created from runs fix - [#​9623](https://redirect.github.com/langchain-ai/langchainjs/pull/9623) [`ade8b8a`](ade8b8af0b) Thanks [@​christian-bromann](https://redirect.github.com/christian-bromann)! - fix(langchain): properly retrieve structured output from thinking block - [#​9637](https://redirect.github.com/langchain-ai/langchainjs/pull/9637) [`88bb788`](88bb7882fa) Thanks [@​christian-bromann](https://redirect.github.com/christian-bromann)! - fix(langchain): Prevent functions from being accidentally assignable to AgentMiddleware - [#​8964](https://redirect.github.com/langchain-ai/langchainjs/pull/8964) [`38ff1b5`](38ff1b55d3) Thanks [@​jnjacobson](https://redirect.github.com/jnjacobson)! - add support for anyOf, allOf, oneOf in openapi conversion - [#​9640](https://redirect.github.com/langchain-ai/langchainjs/pull/9640) [`aa8c4f8`](aa8c4f867a) Thanks [@​christian-bromann](https://redirect.github.com/christian-bromann)! - fix(langchain): prevent summarization middleware from leaking streaming events - [#​9648](https://redirect.github.com/langchain-ai/langchainjs/pull/9648) [`29a8480`](29a8480799) Thanks [@​christian-bromann](https://redirect.github.com/christian-bromann)! - fix(langchain): allow to set strict tag manually in providerStrategy [#​9578](https://redirect.github.com/langchain-ai/langchainjs/issues/9578) - [#​9630](https://redirect.github.com/langchain-ai/langchainjs/pull/9630) [`a2df2d4`](a2df2d422e) Thanks [@​nephix](https://redirect.github.com/nephix)! - fix(summary-middleware): use summaryPrefix or fall back to default prefix - Updated dependencies \[[`005c729`](005c72903b), [`ab78246`](ab78246275), [`8cc81c7`](8cc81c7cee), [`f32e499`](f32e4991d0), [`a28d83d`](a28d83d49d), [`2e5ad70`](2e5ad70d16), [`e456c66`](e456c661aa), [`1cfe603`](1cfe603e97)]: - [@​langchain/core](https://redirect.github.com/langchain/core)@​1.1.5 ### [`v1.1.5`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/langchain%401.1.5) [Compare Source](https://redirect.github.com/langchain-ai/langchainjs/compare/langchain@1.1.4...langchain@1.1.5) ##### Patch Changes - Updated dependencies \[[`0bade90`](0bade90ed4), [`6c40d00`](6c40d00e92)]: - [@​langchain/core](https://redirect.github.com/langchain/core)@​1.1.4 ### [`v1.1.4`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/%40langchain/core%401.1.4) [Compare Source](https://redirect.github.com/langchain-ai/langchainjs/compare/langchain@1.1.3...langchain@1.1.4) ##### Patch Changes - [#​9575](https://redirect.github.com/langchain-ai/langchainjs/pull/9575) [`0bade90`](0bade90ed4) Thanks [@​hntrl](https://redirect.github.com/hntrl)! - bin p-retry - [#​9574](https://redirect.github.com/langchain-ai/langchainjs/pull/9574) [`6c40d00`](6c40d00e92) Thanks [@​hntrl](https://redirect.github.com/hntrl)! - Revert "fix([@​langchain/core](https://redirect.github.com/langchain/core)): update and bundle dependencies ([#​9534](https://redirect.github.com/langchain-ai/langchainjs/issues/9534))" ### [`v1.1.3`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/%40langchain/core%401.1.3) [Compare Source](https://redirect.github.com/langchain-ai/langchainjs/compare/langchain@1.1.2...langchain@1.1.3) ##### Patch Changes - [#​9534](https://redirect.github.com/langchain-ai/langchainjs/pull/9534) [`bd2c46e`](bd2c46e09e) Thanks [@​christian-bromann](https://redirect.github.com/christian-bromann)! - fix([@​langchain/core](https://redirect.github.com/langchain/core)): update and bundle `p-retry`, `ansi-styles`, `camelcase` and `decamelize` dependencies - [#​9544](https://redirect.github.com/langchain-ai/langchainjs/pull/9544) [`487378b`](487378bf14) Thanks [@​hntrl](https://redirect.github.com/hntrl)! - fix tool chunk concat behavior ([#​9450](https://redirect.github.com/langchain-ai/langchainjs/issues/9450)) - [#​9505](https://redirect.github.com/langchain-ai/langchainjs/pull/9505) [`138e7fb`](138e7fb628) Thanks [@​chosh-dev](https://redirect.github.com/chosh-dev)! - feat: replace btoa with toBase64Url for encoding in drawMermaidImage ### [`v1.1.2`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/%40langchain/core%401.1.2) [Compare Source](https://redirect.github.com/langchain-ai/langchainjs/compare/langchain@1.1.1...langchain@1.1.2) ##### Patch Changes - [#​9511](https://redirect.github.com/langchain-ai/langchainjs/pull/9511) [`833f578`](833f57834d) Thanks [@​dqbd](https://redirect.github.com/dqbd)! - allow parsing more partial JSON ### [`v1.1.1`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/%40langchain/core%401.1.1) ##### Patch Changes - [#​9495](https://redirect.github.com/langchain-ai/langchainjs/pull/9495) [`636b994`](636b99459b) Thanks [@​gsriram24](https://redirect.github.com/gsriram24)! - fix: use dynamic import for p-retry to support CommonJS environments - [#​9531](https://redirect.github.com/langchain-ai/langchainjs/pull/9531) [`38f0162`](38f0162b7b) Thanks [@​hntrl](https://redirect.github.com/hntrl)! - add `extras` to tools ### [`v1.1.0`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/%40langchain/anthropic%401.1.0) ##### Minor Changes - [#​9424](https://redirect.github.com/langchain-ai/langchainjs/pull/9424) [`f17b2c9`](f17b2c9db0) Thanks [@​hntrl](https://redirect.github.com/hntrl)! - add support for `betas` param - [#​9424](https://redirect.github.com/langchain-ai/langchainjs/pull/9424) [`f17b2c9`](f17b2c9db0) Thanks [@​hntrl](https://redirect.github.com/hntrl)! - add support for native structured output ##### Patch Changes - [#​9424](https://redirect.github.com/langchain-ai/langchainjs/pull/9424) [`f17b2c9`](f17b2c9db0) Thanks [@​hntrl](https://redirect.github.com/hntrl)! - bump sdk version ### [`v1.0.6`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/langchain%401.0.6) [Compare Source](https://redirect.github.com/langchain-ai/langchainjs/compare/langchain@1.0.5...langchain@1.0.6) ##### Patch Changes - [#​9434](https://redirect.github.com/langchain-ai/langchainjs/pull/9434) [`f7cfece`](f7cfecec29) Thanks [@​deepansh946](https://redirect.github.com/deepansh946)! - Updated error handling behaviour of AgentNode ### [`v1.0.5`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/langchain%401.0.5) ##### Patch Changes - [#​9403](https://redirect.github.com/langchain-ai/langchainjs/pull/9403) [`944bf56`](944bf56ff0) Thanks [@​christian-bromann](https://redirect.github.com/christian-bromann)! - improvements to toolEmulator middleware - [#​9388](https://redirect.github.com/langchain-ai/langchainjs/pull/9388) [`831168a`](831168a545) Thanks [@​hntrl](https://redirect.github.com/hntrl)! - use `profile.maxInputTokens` in summarization middleware - [#​9393](https://redirect.github.com/langchain-ai/langchainjs/pull/9393) [`f1e2f9e`](f1e2f9eeb3) Thanks [@​christian-bromann](https://redirect.github.com/christian-bromann)! - align context editing with summarization interface - [#​9427](https://redirect.github.com/langchain-ai/langchainjs/pull/9427) [`bad7aea`](bad7aea86d) Thanks [@​dqbd](https://redirect.github.com/dqbd)! - fix(langchain): add tool call contents and tool call ID to improve token count approximation - [#​9396](https://redirect.github.com/langchain-ai/langchainjs/pull/9396) [`ed6b581`](ed6b581e52) Thanks [@​christian-bromann](https://redirect.github.com/christian-bromann)! - rename exit behavior from throw to error ### [`v1.0.4`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/%40langchain/community%401.0.4) ##### Patch Changes - [#​9326](https://redirect.github.com/langchain-ai/langchainjs/pull/9326) [`3e0cab6`](3e0cab61b3) Thanks [@​ayanyev](https://redirect.github.com/ayanyev)! - Milvus vector store client: ignore auto-calculated fields in collection schema during payload validation - Updated dependencies \[[`415cb0b`](415cb0bfd2), [`a2ad61e`](a2ad61e787), [`34c472d`](34c472d129)]: - [@​langchain/openai](https://redirect.github.com/langchain/openai)@​1.1.2 - [@​langchain/classic](https://redirect.github.com/langchain/classic)@​1.0.4 ### [`v1.0.3`](https://redirect.github.com/langchain-ai/langchainjs/releases/tag/%40langchain/google-gauth%401.0.3) ##### Patch Changes - Updated dependencies \[]: - [@​langchain/google-common](https://redirect.github.com/langchain/google-common)@​1.0.3 </details> --- ### Configuration 📅 **Schedule**: Branch creation - "" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/googleapis/genai-toolbox). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi42Ni4xNCIsInVwZGF0ZWRJblZlciI6IjQyLjY2LjE0IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Co-authored-by: Yuan Teoh <45984206+Yuan325@users.noreply.github.com>
51 KiB
51 KiB