Summary
A serialization injection vulnerability exists in LangChain's dumps() and dumpd() functions. The functions do not escape dictionaries with 'lc' keys when serializing free-form dictionaries. 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 dumps() and dumpd(): these functions failed to escape user-controlled dictionaries containing 'lc' keys. When this unescaped data was later deserialized via load() or loads(), 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, additionalkwargs, or responsemetadata 2. Class instantiation within trusted namespaces: Injected manifests could instantiate any Serializable subclass, but only within the pre-approved trusted namespaces (langchaincore, langchain, langchaincommunity). This includes classes with side effects in init (network calls, file operations, etc.). Note that namespace validation was already enforced before this patch, so arbitrary classes outside these trusted namespaces could not be instantiated.
Security hardening
This patch fixes the escaping bug in dumps() and dumpd() and introduces new restrictive defaults in load() and loads(): allowlist enforcement via allowedobjects="core" (restricted to serialization mappings), secretsfromenv changed from True to False, and default Jinja2 template blocking via initvalidator. These are breaking changes for some use cases.
Who is affected?
Applications are vulnerable if they:
1. Use astreamevents(version="v1") — The v1 implementation internally uses vulnerable serialization. Note: astreamevents(version="v2") is not vulnerable. 2. Use Runnable.astreamlog() — This method internally uses vulnerable serialization for streaming outputs. 3. Call dumps() or dumpd() on untrusted data, then deserialize with load() or loads() — 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. 4. Deserialize untrusted data with load() or loads() — Directly deserializing untrusted data that may contain injected 'lc' structures. 5. Use RunnableWithMessageHistory — Internal serialization in message history handling. 6. Use InMemoryVectorStore.load() to deserialize untrusted documents. 7. Load untrusted generations from cache using langchain-community caches. 8. Load untrusted manifests from the LangChain Hub via hub.pull. 9. Use StringRunEvaluatorChain on untrusted runs. 10. Use createlcstore or createkvdocstore with untrusted documents. 11. Use MultiVectorRetriever with byte stores containing untrusted documents. 12. Use LangSmithRunChatLoader with runs containing untrusted messages.
The most common attack vector is through LLM response fields like additionalkwargs or responsemetadata, 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": ["ENVVAR"]} to load environment variables during deserialization (when secretsfromenv=True, which was the old default). They can also instantiate classes with controlled parameters by injecting constructor structures to instantiate any class within trusted namespaces 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 (the old default) - LLM responses in additionalkwargs can be controlled via prompt injection
Exploit example
python from langchaincore.load import dumps, load import os
Attacker injects secret structure into user-controlled data attackerdict = { "userdata": { "lc": 1, "type": "secret", "id": ["OPENAIAPIKEY"] } }
serialized = dumps(attackerdict) # Bug: does NOT escape the 'lc' key
os.environ["OPENAIAPIKEY"] = "sk-secret-key-12345" deserialized = load(serialized, secretsfromenv=True)
print(deserialized["userdata"]) # "sk-secret-key-12345" - SECRET LEAKED!
Security hardening changes (breaking changes)
This patch introduces three breaking changes to load() and loads():
1. New allowedobjects parameter (defaults to 'core'): Enforces allowlist of classes that can be deserialized. The 'all' option corresponds to the list of objects specified in mappings.py while the 'core' option limits to objects within langchaincore. We recommend that users explicitly specify which objects they want to allow for serialization/deserialization. 2. secretsfromenv default changed from True to False: Disables automatic secret loading from environment 3. New initvalidator parameter (defaults to defaultinitvalidator): Blocks Jinja2 templates by default
Migration guide
No changes needed for most users
If you're deserializing standard LangChain types (messages, documents, prompts, trusted partner integrations like ChatOpenAI, ChatAnthropic, etc.), your code will work without changes:
python from langchaincore.load import load
Uses default allowlist from serialization mappings obj = load(serializeddata)
For custom classes
If you're deserializing custom classes not in the serialization mappings, add them to the allowlist:
python from langchaincore.load import load from mypackage import MyCustomClass
Specify the classes you need obj = load(serializeddata, allowedobjects=[MyCustomClass])
For Jinja2 templates
Jinja2 templates are now blocked by default because they can execute arbitrary code. If you need Jinja2 templates, pass initvalidator=None:
python from langchaincore.load import load from langchaincore.prompts import PromptTemplate
obj = load( serializeddata, allowedobjects=[PromptTemplate], initvalidator=None )
[!WARNING] Only disable initvalidator if you trust the serialized data. Jinja2 templates can execute arbitrary Python code.
For secrets from environment
secretsfromenv now defaults to False. If you need to load secrets from environment variables:
python from langchaincore.load import load
obj = load(serializeddata, secretsfromenv=True)
Credits
Dumps bug was reported by @yardenporat Changes for security hardening due to findings from @0xn3va and @VladimirEliTokarev
Description
The Model Context Protocol (MCP) Python SDK does not enable DNS rebinding protection by default for HTTP-based servers. When an HTTP-based MCP server is run on localhost without authentication using FastMCP with streamable HTTP or SSE transport, and has not configured TransportSecuritySettings, a malicious website could exploit DNS rebinding to bypass same-origin policy restrictions and send requests to the local MCP server. This could allow an attacker to invoke tools or access resources exposed by the MCP server on behalf of the user in those limited circumstances.
Note that running HTTP-based MCP servers locally without authentication is not recommended per MCP security best practices. This issue does not affect servers using stdio transport.
Servers created via FastMCP() now have DNS rebinding protection enabled by default when the host parameter is 127.0.0.1 or localhost. Users are advised to update to version 1.23.0 to receive this automatic protection. Users with custom low-level server configurations using StreamableHTTPSessionManager or SseServerTransport directly should explicitly configure TransportSecuritySettings when running an unauthenticated server on localhost.
A XSS vulnerability exists in in React Router's meta()/<Meta> APIs in Framework Mode when generating script:ld+json tags which could allow arbitrary JavaScript execution during SSR if untrusted content is used to generate the tag.
[!NOTE] This does not impact applications using Declarative Mode (<BrowserRouter>) or Data Mode (createBrowserRouter/<RouterProvider>).
Summary A zip bomb can be used to execute a DoS against the aiohttp server.
Impact An attacker may be able to send a compressed request that when decompressed by aiohttp could exhaust the host's memory.
------
Patch: https://github.com/aio-libs/aiohttp/commit/2b920c39002cee0ec5b402581779bbaaf7c9138a
ajv (Another JSON Schema Validator) before 8.18.0 is vulnerable to Regular Expression Denial of Service (ReDoS) when the $data option is enabled. The pattern keyword accepts runtime data via JSON Pointer syntax ($data reference), which is passed directly to the JavaScript RegExp() constructor without validation. An attacker can inject a malicious regex pattern (e.g., "^(a|a)$") combined with crafted input to cause catastrophic backtracking. A 31-character payload causes approximately 44 seconds of CPU blocking, with each additional character doubling execution time. This enables complete denial of service with a single HTTP request against any API using ajv with $data: true for dynamic schema validation. This issue is also fixed in version 6.14.0.
IBM Concert 1.0.0 through 2.2.0 uses weaker than expected cryptographic algorithms that could allow an attacker to decrypt highly sensitive information
A flaw was found in OpenShift API, as admission checks do not enforce "custom-host" permissions. This issue could allow an attacker to violate the boundaries, as permissions will not be applied.
Insufficiently specific bounds checking on authorization header could lead to denial of service in the Temporal server on all platforms due to excessive memory allocation. This issue affects all platforms and versions of OSS Server prior to 1.26.3, 1.27.3, and 1.28.1 (i.e., fixed in 1.26.3, 1.27.3, and 1.28.1 and later). Temporal Cloud services are not impacted.
Impact
Multiple (unprefixed) classnames could be added in markdown source by using character references. This could make rendered user supplied markdown code elements appear like the rest of the page. The following markdown:
markdown js xss
Would create <pre><code class="language-js xss"></code></pre> If your page then applied .xss classes (or listeners in JS), those apply to this element. For more info see <https://github.com/ChALkeR/notes/blob/master/Improper-markup-sanitization.md#unsanitized-class-attribute>
Patches
The bug was patched. When using regular semver, run npm install. For exact ranges, make sure to use 13.2.1.
Workarounds
Update.
References
bug introduced in https://github.com/syntax-tree/mdast-util-to-hast/commit/6fc783ae6abdeb798fd5a68e7f3f21411dde7403 bug fixed in https://github.com/syntax-tree/mdast-util-to-hast/commit/ab3a79570a1afbfa7efef5d4a0cd9b5caafbc5d7
Summary When assert statements are bypassed, an infinite loop can occur, resulting in a DoS attack when processing a POST body.
Impact If optimisations are enabled (-O or PYTHONOPTIMIZE=1), and the application includes a handler that uses the Request.post() method, then an attacker may be able to execute a DoS attack with a specially crafted message.
------
Patch: https://github.com/aio-libs/aiohttp/commit/bc1319ec3cbff9438a758951a30907b072561259
Summary A request can be crafted in such a way that an aiohttp server's memory fills up uncontrollably during processing.
Impact If an application includes a handler that uses the Request.post() method, an attacker may be able to freeze the server by exhausting the memory.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/b7dbd35375aedbcd712cbae8ad513d56d11cce60
Summary
Handling of chunked messages can result in excessive blocking CPU usage when receiving a large number of chunks.
Impact
If an application makes use of the request.read() method in an endpoint, it may be possible for an attacker to cause the server to spend a moderate amount of blocking CPU time (e.g. 1 second) while processing the request. This could potentially lead to DoS as the server would be unable to handle other requests during that time.
-----
Patch: https://github.com/aio-libs/aiohttp/commit/dc3170b56904bdf814228fae70a5501a42a6c712 Patch: https://github.com/aio-libs/aiohttp/commit/4ed97a4e46eaf61bd0f05063245f613469700229
Description: During some analysis today on npm's node-tar package I came across the folder creation process, Basicly if you provide node-tar with a path like this ./a/b/c/foo.txt it would create every folder and sub-folder here a, b and c until it reaches the last folder to create foo.txt, In-this case I noticed that there's no validation at all on the amount of folders being created, that said we're actually able to CPU and memory consume the system running node-tar and even crash the nodejs client within few seconds of running it using a path with too many sub-folders inside
Steps To Reproduce: You can reproduce this issue by downloading the tar file I provided in the resources and using node-tar to extract it, you should get the same behavior as the video
Proof Of Concept: Here's a video show-casing the exploit:
Impact
Denial of service by crashing the nodejs client when attempting to parse a tar archive, make it run out of heap memory and consuming server CPU and memory resources
Report resources payload.txt archeive.tar.gz
Note This report was originally reported to GitHub bug bounty program, they asked me to report it to you a month ago
If the PATH environment variable contains paths which are executables (rather than just directories), passing certain strings to LookPath ("", ".", and ".."), can result in the binaries listed in the PATH being unexpectedly returned.
Issue summary: A timing side-channel which could potentially allow remote recovery of the private key exists in the SM2 algorithm implementation on 64 bit ARM platforms.
Impact summary: A timing side-channel in SM2 signature computations on 64 bit ARM platforms could allow recovering the private key by an attacker..
While remote key recovery over a network was not attempted by the reporter, timing measurements revealed a timing signal which may allow such an attack.
OpenSSL does not directly support certificates with SM2 keys in TLS, and so this CVE is not relevant in most TLS contexts. However, given that it is possible to add support for such certificates via a custom provider, coupled with the fact that in such a custom provider context the private key may be recoverable via remote timing measurements, we consider this to be a Moderate severity issue.
The FIPS modules in 3.5, 3.4, 3.3, 3.2, 3.1 and 3.0 are not affected by this issue, as SM2 is not an approved algorithm.
github.com/nwaples/rardecode versions <=2.1.1 fail to restrict the dictionary size when reading large RAR dictionary sizes, which allows an attacker to provide a specially crafted RAR file and cause Denial of Service via an Out Of Memory Crash.
Summary The Python HTTP parser may allow a request smuggling attack with the presence of non-ASCII characters.
Impact If a pure Python version of aiohttp is installed (i.e. without the usual C extensions) or AIOHTTPNOEXTENSIONS is enabled, then an attacker may be able to execute a request smuggling attack to bypass certain firewalls or proxy protections.
------
Patch: https://github.com/aio-libs/aiohttp/commit/32677f2adfd907420c078dda6b79225c6f4ebce0
Summary Path normalization for static files prevents path traversal, but opens up the ability for an attacker to ascertain the existence of absolute path components.
Impact If an application uses web.static() (not recommended for production deployments), it may be possible for an attacker to ascertain the existence of path components.
------
Patch: https://github.com/aio-libs/aiohttp/commit/f2a86fd5ac0383000d1715afddfa704413f0711e
IBM Concert 1.0.0 through 2.0.0 could allow a local user to forge log files to impersonate other users or hide their identity due to improper neutralization of output.
IBM Concert 1.0.0 through 2.2.0 contains hard-coded credentials that could be obtained by a local user.
IBM Concert 1.0.0 through 2.2.0 could allow an attacker to access sensitive information in memory due to the buffer not properly clearing resources.
IBM Concert 1.0.0 through 2.2.0 creates temporary files with predictable names, which allows local users to overwrite arbitrary files via a symlink attack.
Summary Files denied by server.fs.deny were sent if the URL ended with \ when the dev server is running on Windows.
Impact Only apps that match the following conditions are affected:
- explicitly exposes the Vite dev server to the network (using --host or server.host config option) - running the dev server on Windows
Details server.fs.deny can contain patterns matching against files (by default it includes .env, .env., .{crt,pem} as such patterns). These patterns were able to bypass by using a back slash(\). The root cause is that fs.readFile('/foo.png/') loads /foo.png.
PoC shell npm create vite@latest cd vite-project/ cat "secret" > .env npm install npm run dev curl --request-target /.env\ http://localhost:5173 <img width="1593" height="616" alt="image" src="https://github.com/user-attachments/assets/36212f4e-1d3c-4686-b16f-16b35ca9e175" />
Issue summary: An application using the OpenSSL HTTP client API functions may trigger an out-of-bounds read if the 'noproxy' environment variable is set and the host portion of the authority component of the HTTP URL is an IPv6 address.
Impact summary: An out-of-bounds read can trigger a crash which leads to Denial of Service for an application.
The OpenSSL HTTP client API functions can be used directly by applications but they are also used by the OCSP client functions and CMP (Certificate Management Protocol) client implementation in OpenSSL. However the URLs used by these implementations are unlikely to be controlled by an attacker.
In this vulnerable code the out of bounds read can only trigger a crash. Furthermore the vulnerability requires an attacker-controlled URL to be passed from an application to the OpenSSL function and the user has to have a 'noproxy' environment variable set. For the aforementioned reasons the issue was assessed as Low severity.
The vulnerable code was introduced in the following patch releases: 3.0.16, 3.1.8, 3.2.4, 3.3.3, 3.4.0 and 3.5.0.
The FIPS modules in 3.5, 3.4, 3.3, 3.2, 3.1 and 3.0 are not affected by this issue, as the HTTP client implementation is outside the OpenSSL FIPS module boundary.
IBM Concert 1.0.0 through 2.2.0 transmits data in clear text that could allow an attacker to obtain sensitive information using man in the middle techniques.
IBM Concert 1.0.0 through 2.2.0 could allow a local user to obtain sensitive information due to missing function level access control.
IBM Concert 1.0.0 through 2.2.0 could allow a privileged user to perform unauthorized actions due to improper restriction of channel communication to intended endpoints.
When using http.CrossOriginProtection, the AddInsecureBypassPattern method can unexpectedly bypass more requests than intended. CrossOriginProtection then skips validation, but forwards the original request path, which may be served by a different handler without the intended security protections.
Summary
It is possible to put data in front of an LZMA-encoded byte stream without detecting the situation while reading the header. This can lead to increased memory consumption because the current implementation allocates the full decoding buffer directly after reading the header. The LZMA header doesn't include a magic number or has a checksum to detect such an issue according to the specification.
Note that the code recognizes the issue later while reading the stream, but at this time the memory allocation has already been done.
Mitigations
The release v0.5.15 includes following mitigations:
- The ReaderConfig DictCap field is now interpreted as a limit for the dictionary size. - The default is 2 Gigabytes - 1 byte (2^31-1 bytes). - Users can check with the [Reader.Header] method what the actual values are in their LZMA files and set a smaller limit using ReaderConfig. - The dictionary size will not exceed the larger of the file size and the minimum dictionary size. This is another measure to prevent huge memory allocations for the dictionary. - The code supports stream sizes only up to a pebibyte (1024^5).
Note that the original v0.5.14 version had a compiler error for 32 bit platforms, which has been fixed by v0.5.15.
Methods affected
Only software that uses lzma.NewReader or lzma.ReaderConfig.NewReader is affected. There is no issue for software using the xz functionality.
I thank @GregoryBuligin for his report, which is provided below.
Summary When unpacking a large number of LZMA archives, even in a single goroutine, if the first byte of the archive file is 0 (a zero byte added to the beginning), an error writeMatch: distance out of range occurs. Memory consumption spikes sharply, and the GC clearly cannot handle this situation.
Details Judging by the error writeMatch: distance out of range, the problems occur in the code around this function. https://github.com/ulikunitz/xz/blob/c8314b8f21e9c5e25b52da07544cac14db277e89/lzma/decoderdict.go#L81
PoC Run a function similar to this one in 1 or several goroutines on a multitude of LZMA archives that have a 0 (a zero byte) added to the beginning. const ProjectLocalPath = "some/path" const TmpDir = "tmp"
func UnpackLZMA(lzmaFile string) error { file, err := os.Open(lzmaFile) if err != nil { return err } defer file.Close()
reader, err := lzma.NewReader(bufio.NewReader(file)) if err != nil { return err }
tmpFile, err := os.CreateTemp(TmpDir, TmpLZMAPrefix) if err != nil { return err } defer func() { tmpFile.Close() = os.Remove(tmpFile.Name()) }()
sha256Hasher := sha256.New() multiWriter := io.MultiWriter(tmpFile, sha256Hasher)
if , err = io.Copy(multiWriter, reader); err != nil { return err }
unpackHash := hex.EncodeToString(sha256Hasher.Sum(nil)) unpackDir := filepath.Join( ProjectLocalPath, unpackHash[:2], ) = os.MkdirAll(unpackDir, DirPerm)
unpackPath := filepath.Join(unpackDir, unpackHash)
return os.Rename(tmpFile.Name(), unpackPath) }
Impact Servers with a small amount of RAM that download and unpack a large number of unverified LZMA archives
A vulnerability exists in the 'min-document' package prior to version 2.19.0, stemming from improper handling of namespace operations in the removeAttributeNS method. By processing malicious input involving the proto property, an attacker can manipulate the prototype chain of JavaScript objects, leading to denial of service or arbitrary code execution. This issue arises from insufficient validation of attribute namespace removal operations, allowing unintended modification of critical object prototypes. The vulnerability remains unaddressed in the latest available version.