Threat database
23 threats
Most recently published first
| Severity | CVSS | Signals | Threat | Source | Published | Score and star |
|---|---|---|---|---|---|---|
| Medium | 6.3 | EPSS 0.3% | Medium6.3EPSS 0.3%CVE Database V5CVE-2026-114386 Pydantic AI Harness before 0.59.0 fails to enforce UsageLimits.tool_calls_limit on nested tool calls dispatched from run_code in the CodeMode toolset. Users or prompt-injected content can make the sandboxed program invoke tools via run_nested_call() without check_before_tool_call, exceeding operator limits on costly or side-effecting tools. | CVE Database V5 | ||
| High | 7.6 | EPSS 0.2% | CVE-2026-107295pydantic-ai · Cross-Site Request Forgery (CSRF) High7.6EPSS 0.2%CVE Database V5CVE-2026-107295 ### Summary The Pydantic AI development web chat UI (`Agent.to_web()`, `clai web`) did not check the content type of requests to its chat endpoint. This allowed a website visited by a developer to submit a request to a chat UI running on that developer's machine, causing the served agent to run and to execute its tools with the privileges and credentials of the local process. Binding the web UI to localhost — the default — does not prevent this, because a page open in the developer's browser can reach the loopback address. ### Impact Applications and developers serving an agent through `Agent.to_web()` or `clai web`. The consequences depend on the tools the served agent exposes, and can include data disclosure as well as unwanted tool side effects. Tools marked `requires_approval=True` were not protected either, because the endpoint trusts approval decisions relayed by the client. ### Mitigation Upgrade to a patched version. The chat endpoint now requires `Content-Type: application/json` and rejects other requests before the request body is parsed and before the agent runs. The bundled chat UI already sends this header; scripts and other non-browser clients that call the endpoint directly may need to be updated to send it. If you cannot upgrade, don't run the web UI while browsing untrusted sites, stop it when you aren't using it, and don't serve an agent with side-effecting tools through it. ### Credits - Thai Son Dinh from VinSOC Labs (R&D) | CVE Database V5 | ||
| Medium | 6.5 | EPSS 0.4% | CVE-2026-107294pydantic-ai · Uncontrolled Resource Consumption Medium6.5EPSS 0.4%CVE Database V5CVE-2026-107294 CVE-2026-107294 is a medium severity vulnerability in pydantic-ai, a Python agent framework for Generative AI applications. Versions from 1.77.0 up to but not including 1.107.2, and from 2.0.0b1 up to but not including 2.24.0, are affected. The issue involves uncontrolled resource consumption due to buffering the entire HTTP response body before applying content-size controls in certain media download components. This can allow an attacker to cause a denial of service by exhausting process memory and crashing the worker. The vulnerability affects media types such as ImageUrl, DocumentUrl, VideoUrl, and AudioUrl. SSRF protections remain effective, limiting the impact to availability. The issue is fixed in versions 1.107.2 and 2.24.0. | CVE Database V5 | ||
| Low | 2.3 | EPSS 0.3% | Low2.3EPSS 0.3%CVE Database V5CVE-2026-107293 ### Summary Pydantic AI's OpenTelemetry instrumentation supports `InstrumentationSettings(include_content=False)` to exclude message content — user prompts, model completions, tool call arguments and responses — from exported telemetry, so that agents can be monitored without sending sensitive content to the observability backend. Retry prompts — the feedback messages Pydantic AI sends back to the model when its output fails validation or an output validator raises `ModelRetry` — were not covered by this setting when they were not associated with a tool call, as with structured output modes that don't use tool calls (e.g. `NativeOutput` or `PromptedOutput`) and output validators applied to text output. Their full content was recorded on model request spans even with `include_content=False`. Since validation feedback can quote invalid values from the model's response, message content that the setting was configured to withhold could reach the telemetry backend. ### Details Retry prompts without an associated tool call were serialized into span message attributes (such as `gen_ai.input.messages` and `pydantic_ai.all_messages`) as regular text parts, and this path did not apply the `include_content` check that every other message part applies. Retry prompts tied to a tool call, and all other message content, were redacted correctly. ### Impact This does not grant an attacker any new access to the agent or its data: the content is only visible to whoever can read the exported telemetry. The exposure matters when traces are exported to a destination whose audience is broader or less trusted than the agent's own data — a third-party observability vendor or a shared backend — which is the scenario `include_content=False` exists for. The disclosed content is limited to retry feedback: validation error details, which can quote invalid values from the model's output, or output-validator `ModelRetry` messages. ### Who Is Affected You are affected if you enabled instrumentation with `include_content=False` and your agent can produce retry prompts outside of tool calls: it uses a structured output mode that doesn't rely on tool calls (such as `NativeOutput` or `PromptedOutput`), or output validators on text output. You are not affected if you don't set `include_content=False`, or if all of your agent's retries come from tool calls (including the default tool-based structured output mode), which were redacted correctly. ### Remediation Upgrade to a patched version; retry prompt content now honors `include_content=False` like all other message content. If you rely on this setting, consider reviewing previously exported traces for retry prompt content that should not have been recorded. ### Workaround for Unpatched Versions If you cannot upgrade, scrub or drop the message attributes (`gen_ai.input.messages`, `gen_ai.output.messages`, `pydantic_ai.all_messages`) in your telemetry pipeline (for example with an OpenTelemetry Collector processor), or use tool-based structured output modes, whose retry feedback honors `include_content=False`. ### Credits Reported privately by the University of Sydney Security Research Team (Liyi Zhou, Ziyue Wang, Strick, Maurice, Chenchen Yu), and later independently discovered and reported publicly, with a fix, by @sean-kim05. | CVE Database V5 | ||
| Medium | 6.4 | EPSS 0.1% | CVE-2026-107292pydantic-ai · Origin Validation Error Medium6.4EPSS 0.1%CVE Database V5CVE-2026-107292 CVE-2026-107292 is an origin validation error in pydantic-ai affecting versions from 1.34.0 up to but not including 2.30.0. The vulnerability allows DNS rebinding attacks via the Host header in the Agent.to_web() and clai web chat server, enabling a malicious website to interact with a loopback-hosted agent as a same-origin service. This can lead to unauthorized execution of agent tools with local process privileges, causing data disclosure and unwanted side effects. The issue is fixed in versions 1.107.5 and 2.30.0. | CVE Database V5 | ||
| Low | 2.3 | EPSS 0.5% | Low2.3EPSS 0.5%CVE Database V5CVE-2026-107291 Pydantic AI is a Python agent framework for building applications and workflows with Generative AI. From 0.3.4 until 1.107.6 and 2.44.0, OpenTelemetry instrumentation configured with InstrumentationSettings(include_content=False) can still export sensitive agent content through exception.message and exception.stacktrace events, error status descriptions, and model_request_parameters containing instructions or the prompted_output_template. The exposed data is available to readers of the configured telemetry backend and can include tool feedback, provider error bodies, runtime instructions, and structured-output templates even though message attributes are redacted. This issue does not grant new access to agent data, and deployments that do not use include_content=False are not affected by the setting bypass. This issue is fixed in versions 1.107.6 and 2.44.0. | CVE Database V5 | ||
| Medium | 6.5 | EPSS 0.4% | CVE-2026-107290pydantic-ai · Inefficient Regular Expression Complexity Medium6.5EPSS 0.4%CVE Database V5CVE-2026-107290 CVE-2026-107290 is a vulnerability in pydantic-ai affecting versions from 1.77.0 up to but not including 1.107.6, and from 2.0.0b1 up to but not including 2.44.0. It involves inefficient regular expression complexity in the local web_fetch_tool and WebFetch local fallback process, which process server-controlled responses with quadratic time complexity in title extraction, whitespace normalization, and ordered-list numbering. This can cause the event loop to stall for an extended period, impacting other agent runs and requests. The issue is fixed in versions 1.107.6 and 2.44.0. | CVE Database V5 | ||
| Medium | 6.8 | EPSS 0.3% | CVE-2026-107289pydantic-ai · Server-Side Request Forgery (SSRF) Medium6.8EPSS 0.3%CVE Database V5CVE-2026-107289 Pydantic AI is a Python agent framework for building applications and workflows with Generative AI. From 1.56.0 until 1.107.6 and 2.44.0, applications that opt attacker-influenced URLs into local network access through FileUrl with force_download='allow-local' or web_fetch_tool with allow_local_urls=True can bypass the cloud-metadata blocklist by appending an IPv6 zone identifier to an IPv6 metadata address. IPv6Address equality and hashing include the zone identifier, so the blocklist comparison fails even though the network stack ignores the zone on a non-link-local destination and reaches the metadata service, potentially exposing cloud IAM credentials. The opt-in settings are disabled by default, and the issue requires an IPv6-enabled environment. This issue is fixed in versions 1.107.6 and 2.44.0. | CVE Database V5 | ||
| Low | 3.7 | EPSS 0.4% | CVE-2026-107288pydantic-ai · Server-Side Request Forgery (SSRF) Low3.7EPSS 0.4%CVE Database V5CVE-2026-107288 Pydantic AI is a Python agent framework for building applications and workflows with Generative AI. From 1.77.0 until 1.107.6 and 2.44.0, the local web_fetch_tool and the WebFetch local fallback compare blocked_domains entries with a URL hostname before both values are normalized to the form used by getaddrinfo. An attacker-influenced model can use an equivalent IDNA spelling, non-ASCII label separator, case variation, or trailing root label that resolves to a blocked host but does not match the configured string, causing the application to fetch that host with its own privileges. allowed_domains fails closed for unmatched spellings, and private-IP and cloud-metadata protections remain effective. This issue is fixed in versions 1.107.6 and 2.44.0. | CVE Database V5 | ||
| Medium | 6.5 | EPSS 0.3% | CVE-2026-107287pydantic-ai · Uncontrolled Resource Consumption Medium6.5EPSS 0.3%CVE Database V5CVE-2026-107287 CVE-2026-107287 is a medium severity vulnerability in pydantic-ai affecting versions from 1.77.0 up to but not including 1.107.7, and from 2.0.0b1 up to but not including 2.52.0. The issue involves uncontrolled resource consumption during HTML-to-Markdown conversion of attacker-controlled HTML with deeply nested block elements, causing excessive CPU and memory use. This can delay processing of other tasks. The vulnerability is fixed in versions 1.107.7 and 2.52.0. | CVE Database V5 | ||
| High | 7.5 | EPSS 0.4% | High7.5EPSS 0.4%CVE Database V5CVE-2026-107286 > This issue was posted by Codex Desktop using gpt-6.1-sol on behalf of David. ### Summary Applications that wrap a model with `ConcurrencyLimitedModel` or `limit_model_concurrency` can permanently lose shared concurrency capacity when a streamed request releases its slot from a different task than the one that acquired it. This can happen when a stream ends early, and also when a stream is fully consumed using the default `stream_text()` debouncing. In an application that exposes an affected streaming endpoint to network clients and shares a long-lived model limiter across requests, a client can repeatedly start a stream and disconnect. The completed requests retain their slots, eventually preventing subsequent requests that share the limiter from proceeding. Agent-level `max_concurrency` and non-streaming model requests are not affected by this defect. ### Details The built-in limiter uses `anyio.CapacityLimiter`, which associates each acquired slot with its borrowing task. Pydantic AI's streaming lifecycle can acquire the slot on the task consuming the stream and run cleanup on another internal task. The limiter rejects that release, so the slot remains occupied even after the request has ended. Cleanup can raise a `RuntimeError`; a later request on the borrowing task can also fail because that task still holds a slot. Early termination includes stopping iteration, a consumer exception, and cancellation. Fully consuming `stream_text()` with its default `debounce_by=0.1` can also reach the cross-task release path. Fully consumed streams must therefore not be assumed safe. ### Mitigation Upgrade to a patched release of `pydantic-ai` or `pydantic-ai-slim`. If you cannot upgrade yet, use the agent-level `max_concurrency` setting instead of a concurrency-limited model, or avoid streaming runs through a concurrency-limited model. | CVE Database V5 | ||
| High | 7.5 | EPSS 0.6% | High7.5EPSS 0.6%CVE Database V5CVE-2026-84382 ### Summary When decoding a compressed response body (`gzip`, `deflate`, `br`, or `zstd`), HTTPX2 fully decompressed each network read before yielding content to the application. A small compressed input could therefore cause a large intermediate memory allocation, even when the application streamed the response to keep memory usage bounded. ### Details HTTPX2's default transport reads the socket in pieces of up to 64 KiB. Before `2.12.0`, each piece was inflated completely into one intermediate allocation before any decompressed bytes were yielded. At DEFLATE's maximum compression ratio of roughly 1032:1, a 64 KiB compressed chunk can expand to about 64 MiB in one allocation. Brotli and Zstandard responses can cause similarly large amplification. Streaming the response did not prevent these transient allocations. ### Impact Applications that fetch resources from untrusted or attacker-influenced servers - such as webhook receivers, link unfurlers, crawlers, SSRF-reachable fetchers, and redirect followers - can experience memory pressure or out-of-memory termination when processing a malicious compressed response. No authentication or user interaction is required beyond issuing a request to the server. ### Mitigation Upgrade to HTTPX2 `2.12.0` or later. Patched versions decompress responses incrementally with bounded intermediate buffers, including responses with multiple content encodings. | CVE Database V5 | ||
| High | 8.1 | EPSS 0.1% | High8.1EPSS 0.1%CVE Database V5CVE-2026-84381 ### Summary httpcore2 does not start TLS for `wss://` connections routed through a SOCKS5 proxy. The WebSocket opening handshake and all subsequent frames are sent in plaintext through the proxy path, despite the caller selecting the secure `wss` scheme. The transport flaw affects httpcore2 releases before `2.10.0`. HTTPX2 exposed this behavior through its public `Client.websocket()` and `AsyncClient.websocket()` APIs from `2.6.0` through `2.9.1`. ### Details The synchronous and asynchronous SOCKS5 connection implementations upgrade the established proxy tunnel to TLS only when the remote origin scheme is `https`. The equivalent check does not include `wss`. After the SOCKS5 handshake succeeds, the raw stream is therefore passed directly to the HTTP/1.1 connection, which writes the WebSocket upgrade request without first performing a TLS handshake or verifying the destination certificate. For example, an application using HTTPX2 `2.6.0` through `2.9.1` may open an authenticated WebSocket through a SOCKS proxy: ```python import httpx2 with httpx2.Client(proxy="socks5://proxy.example:1080") as client: with client.websocket( "wss://service.example/private?token=query-secret", headers={"Authorization": "Bearer header-secret"}, cookies={"session": "cookie-secret"}, ) as websocket: websocket.send_text("private message") ``` On affected versions, the stream passing through the SOCKS proxy begins with a plaintext request such as: ```text GET /private?token=query-secret HTTP/1.1 Host: service.example Authorization: Bearer header-secret Cookie: session=cookie-secret ``` Before HTTPX2 `2.6.0`, the same underlying httpcore2 behavior could be reached by integrations constructing a WebSocket upgrade request through the low-level transport API, but HTTPX2 did not yet provide its native WebSocket client API. A normal secure WebSocket server will usually reject these plaintext bytes because it expects a TLS ClientHello. However, a malicious or compromised SOCKS proxy can accept the SOCKS connection, observe the plaintext handshake, return a forged `101 Switching Protocols` response, and then read or modify WebSocket frames in both directions. An observer between the proxy and destination may also read the plaintext traffic. RFC 6455 requires a client using a secure WebSocket connection to perform the TLS handshake before sending the WebSocket opening handshake. A `wss` URI promises confidentiality, integrity, and endpoint authentication through TLS. ### Impact An attacker able to control or observe the SOCKS proxy path can obtain URL query parameters, authorization headers, cookies, and application messages that the caller expected TLS to protect. Because no TLS handshake occurs, certificate verification also does not occur, allowing an attacker controlling the proxy to impersonate the WebSocket server and inject or alter messages. Only `wss://` connections routed through a SOCKS5 proxy are affected. Direct `wss://` connections and ordinary `https://` requests through SOCKS already start TLS correctly. ### Mitigation Upgrade HTTPX2 and httpcore2 to `2.10.0` or later. Patched versions start TLS for both `https` and `wss` origins in the synchronous and asynchronous SOCKS5 connection paths. If upgrading is not immediately possible, do not route `wss://` connections through a SOCKS proxy. Use a direct secure WebSocket connection or another transport that performs and verifies TLS to the WebSocket origin. | CVE Database V5 | ||
| Medium | 5.6 | EPSS 0.2% | CVE-2026-84380httpx2 · HTTP Request/Response Smuggling Medium5.6EPSS 0.2%CVE Database V5CVE-2026-84380 ### Summary HTTPX2 can automatically add a `Content-Length` header to a request that already contains a caller-supplied `Transfer-Encoding` header. The resulting HTTP/1.1 request contains both framing headers, which can create an ambiguous message boundary and enable request smuggling or connection desynchronization when processed by intermediaries that disagree about which header takes precedence. ### Details When a request body has a known size, HTTPX2's content encoder returns a default `Content-Length`. `Request._prepare()` applies each default header with `setdefault()`, which only checks whether that same header is already present. It does not check whether the mutually exclusive `Transfer-Encoding` header is present. For example: ```python import httpx2 request = httpx2.Request( "POST", "http://example.com/", headers={"Transfer-Encoding": "chunked"}, content=b"test 123", ) print(request.headers) ``` The request contains both: ```text Transfer-Encoding: chunked Content-Length: 8 ``` On an HTTP/1.1 connection, the body is serialized using chunked transfer coding while both headers are sent on the wire. This violates HTTP message-framing requirements. Fixed-size byte, JSON, form, and known-length multipart bodies can reach the affected path. Streaming bodies with an explicit `Content-Length` are not affected in current HTTPX2 releases because the automatically generated `Transfer-Encoding` is already suppressed in that direction. ### Impact An attacker may be able to use the conflicting framing headers as a request-smuggling or desynchronization primitive. Exploitation requires an application to pass attacker-controlled request framing headers and associated body data to HTTPX2, use HTTP/1.1, and communicate through a proxy or origin that accepts conflicting headers and interprets them differently from another hop. Depending on the downstream infrastructure, successful exploitation could interfere with requests sharing a persistent connection, bypass front-end routing or authorization decisions, or poison responses or caches. Applications that do not forward attacker-controlled `Transfer-Encoding` headers are not directly exposed. ### Mitigation Upgrade to HTTPX2 `2.11.0` or later. Patched versions treat `Content-Length` and `Transfer-Encoding` as mutually exclusive when applying automatically generated request headers. If upgrading is not immediately possible, remove `Transfer-Encoding` and other hop-by-hop framing headers from untrusted input before constructing outbound requests. Applications acting as proxies should derive outbound framing from the body rather than forwarding inbound `Content-Length` or `Transfer-Encoding` headers. | CVE Database V5 | ||
| Medium | 5.3 | EPSS 0.3% | CVE-2026-84379httpx2 · CRLF Injection Medium5.3EPSS 0.3%CVE Database V5CVE-2026-84379 ### Summary HTTPX2 serializes the per-file `Content-Type` and custom headers supplied through the `files=` tuple API directly into the `multipart/form-data` body without validating custom header names or values. An attacker who can influence upload metadata passed to HTTPX2 can use CR or LF characters to terminate a multipart part header and inject additional part headers or end the part header block early. ### Details The three-element file tuple accepts `(filename, content, content_type)`, and the four-element form accepts `(filename, content, content_type, headers)`. `FileField.render_headers()` interpolates the supplied header names and values between CRLF delimiters without validating them. For example: ```python import httpx2 request = httpx2.Request( "POST", "https://example.com/upload", headers={"Content-Type": "multipart/form-data; boundary=BOUNDARY"}, files={ "file": ( "safe.txt", b"payload", "text/plain\r\nX-Injected: true", ) }, ) print(request.read().decode()) ``` The generated body contains an attacker-injected part header: ```text --BOUNDARY Content-Disposition: form-data; name="file"; filename="safe.txt" Content-Type: text/plain X-Injected: true payload --BOUNDARY-- ``` The same issue affects names and values in the custom header mapping from the four-element tuple. Field names and filenames are serialized through a separate escaping path and do not permit CRLF header injection. ### Impact Applications are affected when they pass attacker-controlled upload metadata into the per-file `content_type` or custom `headers` arguments. The receiving server interprets injected lines as genuine multipart part headers. Depending on how that server validates and processes uploads, this can alter part semantics or bypass checks based on part headers. This does not split the outer HTTP request: the injected headers are contained within the multipart body. The concrete security impact therefore depends on the downstream multipart parser and application behavior. ### Mitigation Upgrade to HTTPX2 `2.11.0` or later. Patched versions reject forbidden control characters in multipart part header names and values and raise `ValueError` before serializing the request. If upgrading is not immediately possible, applications should validate custom multipart header names as HTTP field-name tokens. They should reject NUL, CR, LF, other C0 controls except horizontal tab, and DEL in per-file content types and custom header values before passing them to HTTPX2. | CVE Database V5 | ||
| Medium | 5.9 | EPSS 0.3% | CVE-2026-84378httpx2 · Inefficient Algorithmic Complexity Medium5.9EPSS 0.3%CVE Database V5CVE-2026-84378 ### Summary HTTPX2's Server-Sent Events (SSE) parser repeatedly copied and rescanned buffered text when a server split one unterminated line across many response chunks. The total work grows quadratically with the length of the line. An attacker-controlled or compromised SSE endpoint can exploit this behavior to consume excessive client CPU. ### Details Before version 2.10.0, HTTPX2 combined the complete pending SSE line with each newly received chunk and then scanned the combined text for line separators. If an SSE server sends a long line as many small chunks without a line separator, every chunk causes all previously received text to be copied and scanned again. For `n` fixed-size chunks, this results in O(n²) processing. The behavior affects both `httpx2.Client.sse()` and `httpx2.AsyncClient.sse()`. Other response APIs do not use the SSE parsing path. ### Impact Applications that consume SSE from an attacker-controlled or compromised endpoint can experience excessive CPU usage. A crafted stream can block a synchronous worker or the asynchronous event loop that is consuming it, degrading availability for other work in that process. Confidentiality and integrity are not affected. ### Mitigation Upgrade to HTTPX2 2.10.0 or later. SSE parsing now accumulates incomplete line fragments and combines them only when necessary, making processing linear in the amount of received data. HTTPX2 2.10.0 also limits buffered SSE events to 1 MiB by default through `max_event_size`. If upgrading is not immediately possible, only consume SSE from trusted endpoints and enforce an external size or time budget on the stream. | CVE Database V5 | ||
| Medium | 6.8 | EPSS 0.3% | CVE-2026-54249pydantic-ai · Server-Side Request Forgery (SSRF) Medium6.8EPSS 0.3%CVE Database V5CVE-2026-54249 ### Summary A client that can submit message history to a Pydantic AI UI adapter can reference arbitrary files in the application's model-provider or cloud-storage account. The server forwards the reference to the model provider, which fetches it using the server's own credentials, allowing the client to read files it should not have access to. ### Details UI adapters reconstruct file parts from client-submitted message history and forward them to the model provider. File **URL** parts are validated against a scheme allowlist before being forwarded, but `UploadedFile` references — which point to a file by provider file ID or cloud-storage URI (e.g. `s3://…`, `gs://…`) — were forwarded without validation. Because the provider resolves an `UploadedFile` using the server-side identity (IAM role, service account, or provider API key) rather than the client's, a client that crafts message history containing an attacker-chosen `UploadedFile` can cause the server to read objects belonging to its own account or to other tenants, given a referenceable identifier. ### Impact Applications that pass untrusted client-submitted message history to an agent through a UI adapter (such as the Vercel AI adapter). Exploitation requires the attacker to reference a valid file identifier; depending on how the application names objects, such identifiers are not always unguessable. ### Patches Upgrade to `1.106.0` (1.x) or `2.0.0b6` (the 2.x beta line), which validate `UploadedFile` references on client-submitted messages the same way file URLs are validated. ### Workarounds If users cannot upgrade, do not pass untrusted client-submitted message history to the agent, or strip `UploadedFile` parts from incoming messages before running the agent. | CVE Database V5 | ||
| Medium | 6.8 | EPSS 0.4% | CVE-2026-46678pydantic-ai · Server-Side Request Forgery (SSRF) Medium6.8EPSS 0.4%CVE Database V5CVE-2026-46678 ## Summary When an application using Pydantic AI opts a URL into `force_download='allow-local'` (which disables the default block on private/internal IPs), the cloud-metadata blocklist could be bypassed by encoding the metadata IP in an IPv6 transition form (IPv4-mapped IPv6, 6to4, or NAT64). Dual-stack and translated networks route the IPv6 wrapper to the underlying IPv4 endpoint, exposing cloud IAM short-term credentials. This is an incomplete fix of [GHSA-2jrp-274c-jhv3](https://github.com/pydantic/pydantic-ai/security/advisories/GHSA-2jrp-274c-jhv3) / [CVE-2026-25580](https://nvd.nist.gov/vuln/detail/CVE-2026-25580). The parent advisory's remediation guaranteed that "cloud metadata endpoints are always blocked, even with `allow-local`." That guarantee did not hold for IPv6-encoded forms of the metadata IPs. ## Severity Same impact metrics as the parent CVE, but materially narrower attack surface (AC:H instead of AC:L), because exploitation requires the application to have opted into `allow-local` on a URL influenced by untrusted input. ## Who Is Affected Applications are affected **only if** they explicitly opt for `FileUrl` (`ImageUrl`, `AudioUrl`, `VideoUrl`, `DocumentUrl`) into `force_download='allow-local'` on a URL that is, or could be, influenced by untrusted input. Applications are **not** affected if they use any of the bundled integrations to ingest user input, because they do not propagate `force_download` from external data: - `Agent.to_web` / `clai web` - `VercelAIAdapter` - `AGUIAdapter` / `Agent.to_ag_ui` Applications that only download from developer-controlled URLs are not affected. ## Remediation Upgrade to `1.99.0` or later. The cloud-metadata and private-IP blocklists now apply to IPv6 transition forms that route to a blocked IPv4 endpoint (IPv4-mapped IPv6, 6to4, and NAT64 well-known prefix). The blocklists have also been extended to cover additional IANA-reserved IPv4 and IPv6 special-purpose ranges. ## Workaround for Unpatched Versions Avoid passing `force_download='allow-local'` on any URL that could be influenced by untrusted input. If developers must, resolve the hostname themselves and validate the result against their own metadata blocklist — including IPv6-encoded forms — before constructing the `FileUrl`. ## Credits Reported by [j0hndo](mailto:dohyun4466@gmail.com). | CVE Database V5 | ||
| Medium | 6.5 | EPSS 0.3% | CVE-2026-65975pydantic-ai · Incorrect Authorization Medium6.5EPSS 0.3%CVE Database V5CVE-2026-65975 CVE-2026-65975 is an incorrect authorization vulnerability in pydantic-ai, a Python agent framework for Generative AI applications. In affected versions, certain UI adapters improperly sanitize client-submitted tool calls, allowing a remote client to trigger execution of registered server tools with client-supplied arguments, bypassing model-generated argument checks. This flaw is fixed in versions 1.107.1 and 2.5.0. | CVE Database V5 | ||
| Medium | 5.3 | EPSS 0.2% | CVE-2026-58203pydantic-settings · Path Traversal Medium5.3EPSS 0.2%CVE Database V5CVE-2026-58203 ### Summary `NestedSecretsSettingsSource` reads secret values from files in a configured `secrets_dir`. When `secrets_nested_subdir=True`, a directory entry inside `secrets_dir` that is a symbolic link pointing **outside** `secrets_dir` is followed, so files outside the configured directory are read into settings values. The same code path bypasses the documented `secrets_dir_max_size` protection. An attacker or lower-privileged component able to influence entries in the configured secrets directory (for example, a writable or shared secrets mount) can turn this into an unintended local file read into settings and can defeat the advertised loading-size cap. This report does not claim network reachability by itself. ### Details `NestedSecretsSettingsSource` performed two passes over `secrets_dir` using two different, inconsistent directory-traversal implementations: * The size check in `validate_secrets_path()` used `Path.glob('**/*')`, which does **not** descend into a symbolically-linked directory. * The loader in `load_secrets()` used `glob.iglob(f'{path}/**/*', recursive=True)` followed by `read_text()`, which **does** follow symlinked directories and reads through the link target. Because the two passes disagreed on symlinks, a symlinked directory inside `secrets_dir` whose target lives elsewhere was invisible to the size accounting (counted as 0 bytes) while still being fully read by the loader. This produces two distinct problems: 1. **Out-of-tree read (CWE-22 / CWE-59).** A symlinked directory (or file) inside `secrets_dir` that resolves outside it is followed, and the external file's contents are loaded into the corresponding settings field. 2. **`secrets_dir_max_size` bypass (CWE-400).** The size check never sees the out-of-tree content, so the documented size cap is neither respected nor able to reject the oversized external file. A related amplification exists for cyclic in-tree symlinks, which `glob.iglob(recursive=True)` re-traverses, inflating the size accounting and the number of loaded secrets. #### Reproduction In a clean Linux container, with a `secrets_dir` containing a symlink `secrets/db -> /path/outside` and an `outside/passwd` file of 512 bytes, while `secrets_dir_max_size=100`: ```python from pydantic import BaseModel from pydantic_settings import ( BaseSettings, SettingsConfigDict, NestedSecretsSettingsSource, ) class Db(BaseModel): passwd: str | None = None class Settings(BaseSettings): model_config = SettingsConfigDict( secrets_dir='secrets', secrets_nested_subdir=True, secrets_dir_max_size=100, # outside/passwd is 512 bytes ) db: Db = Db() @classmethod def settings_customise_sources( cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings ): return (NestedSecretsSettingsSource(file_secret_settings),) ``` On affected versions, `Settings().db.passwd` is populated with the 512-byte out-of-tree file and **no** `SettingsError` is raised, even though the file exceeds `secrets_dir_max_size`. ### Impact Applications that opt into `NestedSecretsSettingsSource` with `secrets_nested_subdir=True` and load secrets from a directory whose entries can be influenced by an attacker or a lower-privileged component (for example, a writable or shared secrets mount, or a secrets directory partially populated from untrusted input) are affected. The impact is: * **Confidentiality:** files outside the configured `secrets_dir` can be read into settings values (local file read). * **Integrity / availability of the safeguard:** the advertised `secrets_dir_max_size` cap can be bypassed, and cyclic symlinks can inflate resource usage during loading. The vulnerability requires the ability to place a symbolic link inside the configured secrets directory; it is not remotely reachable on its own. Applications that do not use `NestedSecretsSettingsSource`, or that point `secrets_dir` at a directory fully under the application's control, are not affected. ### Mitigation Upgrade to **pydantic-settings 2.14.2**, which: * walks the secrets directory explicitly and only descends into directories whose resolved path stays within `secrets_dir`, so symlinked directories pointing outside are never followed; * uses a single, cycle-safe iterator for both the size check and the loader, so the size accounting and the loaded set are always consistent and each real directory is visited at most once; * skips any file whose resolved path escapes `secrets_dir`, as defense in depth. If upgrading is not immediately possible, ensure the configured `secrets_dir` is fully owned and controlled by the application (no writable or attacker-influenced entries), or avoid `secrets_nested_subdir=True`. | CVE Database V5 |
Showing 1–20 of 23 results