CVE-2026-34070 - LangChain load_prompt path traversal

langchain-core before 1.2.22 allowed legacy prompt-loading APIs to read paths supplied inside prompt configuration dictionaries without rejecting absolute paths or traversal. Applications that accept prompt configs from users, plugins, workflow files, low-code builders, or remote API callers can turn a prompt-import feature into local file disclosure.

The durable fix is not only an upgrade. Repositories should also stop treating legacy prompt config dictionaries as safe interchange formats, migrate to the allow-list based langchain_core.load serialization APIs where possible, and prove prompt imports cannot read secrets, system prompts, credentials, or workspace files.

When to use it

Use this recipe when a LangChain application imports prompt config dictionaries or prompt files from users, tenants, plugins, notebooks, low-code builders, workflow definitions, agents, or remote APIs. It is designed for source-code remediation, prompt-config provenance review, canonical path containment, secret-disclosure prevention, and evidence that untrusted prompt imports cannot read local files.

Inputs

  • langchain-core version, Python dependency/lockfile state, prompt import entrypoints, trusted prompt roots, serialization format, and generated dependency or SBOM reports.
  • Source paths that call load_prompt, load_prompt_from_config, prompt .save(), compatibility wrappers, uploaded prompt config handlers, workflow builders, plugin loaders, or evaluation jobs.
  • Regression fixtures for absolute paths, traversal paths, symlinks, template_path, prefix_path, suffix_path, examples, example_prompt_path, benign prompt configs, and denied file reads.
  • Boundary evidence: prompt authors, tenant/admin/plugin trust model, readable secrets on hosts, prompt artifact storage, logs, disclosure-review owner, and rollout owner.

Affected versions

  • Vulnerable package: langchain-core <1.2.22
  • Fixed package: langchain-core >=1.2.22
  • Affected APIs: legacy prompt-loading paths in langchain_core.prompts.loading, including load_prompt() and load_prompt_from_config()
  • Affected config keys: prompt template paths, few-shot example paths, and example prompt paths that are read from .txt, .json, .yaml, or .yml files
  • Affected surfaces: any app that lets untrusted or semi-trusted parties provide prompt config dictionaries or uploaded prompt configuration files

Indicator-of-exposure

  • The repository depends on langchain-core <1.2.22 directly or through LangChain application packages.
  • Code imports from langchain_core.prompts.loading or calls load_prompt, load_prompt_from_config, prompt .save(), or compatibility wrappers around those functions.
  • Prompt config files are accepted from tenants, admins, plugin authors, agents, workflow definitions, notebooks, UI builders, remote APIs, or model evaluation jobs.
  • Prompt configs can name paths through keys such as template_path, suffix_path, prefix_path, examples, or example_prompt_path.
  • The service host has readable secrets, cloud credentials, Kubernetes config, .env files, internal prompts, prompt logs, or application config in common filesystem locations.

Quick checks:

rg -n "langchain-core|langchain_core\\.prompts\\.loading|load_prompt|load_prompt_from_config|template_path|suffix_path|prefix_path|example_prompt_path|\\.save\\(" .
python -m pip show langchain-core langchain
python -m pip freeze | rg -i "^(langchain-core|langchain)=="
rg -n "prompt.*config|builder|workflow|plugin|load_prompt|template_path|example_prompt_path" src app services packages notebooks tests . 2>/dev/null

Windows:

rg -n "langchain-core|langchain_core\\.prompts\\.loading|load_prompt|load_prompt_from_config|template_path|suffix_path|prefix_path|example_prompt_path|\\.save\\(" .
python -m pip show langchain-core langchain
python -m pip freeze | rg -i "^(langchain-core|langchain)=="
rg -n "prompt.*config|builder|workflow|plugin|load_prompt|template_path|example_prompt_path" src app services packages notebooks tests .

Do not test exposure by reading real secrets, cloud credentials, customer files, internal prompts, or production-mounted paths.

Remediation strategy

  • Upgrade every controlled langchain-core dependency, lockfile, image, generated dependency report, and SBOM to 1.2.22+.
  • Remove or fence legacy prompt config imports for untrusted input. Prefer the newer langchain_core.load serialization APIs and explicit allow-lists for prompt object types.
  • If prompt files must be imported, require repository-owned prompt roots, reject absolute paths and traversal, canonicalize final paths, and deny symlink escapes before opening files.
  • Treat uploaded prompt configs as untrusted code-adjacent data. Require authorization, audit logging, reviewable provenance, size limits, and content validation.
  • Add safe regression checks that use temporary fixture files only and prove prompt import cannot read outside an allowed prompt root.
  • Review logs and artifacts for accidental disclosure if vulnerable prompt imports were exposed to users or agents.

The prompt

You are remediating CVE-2026-34070 / GHSA-qh6h-p6c9-ff54, a LangChain
`langchain-core` path traversal issue in legacy prompt-loading APIs. Produce
exactly one output:

- A reviewer-ready PR/change request that upgrades `langchain-core`, removes
  unsafe legacy prompt config import paths, adds safe regression coverage,
  refreshes generated artifacts, and documents operator review, or
- TRIAGE.md if this repository does not own an affected LangChain runtime or
  any untrusted prompt config import surface.

## Rules

- Scope only CVE-2026-34070 / GHSA-qh6h-p6c9-ff54 and directly related
  LangChain prompt-loading, prompt config, file-read, and serialization
  controls.
- Treat prompt files, system prompts, `.env` files, cloud credentials,
  Kubernetes config, Docker config, API keys, model-provider keys, notebooks,
  user uploads, tenant data, and logs as sensitive.
- Do not read real secrets, production paths, home directories, cloud config,
  customer files, internal prompts, or prompt logs to prove exposure.
- Do not remove authorization, audit logging, prompt review, sandboxing,
  provenance checks, or tests to silence the advisory.
- Do not auto-merge.

## Steps

1. Inventory every LangChain runtime controlled by the repository: Python
   manifests, lockfiles, constraints, notebooks, Dockerfiles, base images,
   generated dependency reports, SBOMs, model-serving images, low-code builder
   services, agent workflow runners, and prompt import/export tooling.
2. Determine every resolved `langchain-core` version. A target is vulnerable if
   it resolves to `<1.2.22`.
3. Search for legacy prompt-loading usage:
   `langchain_core.prompts.loading`, `load_prompt`,
   `load_prompt_from_config`, prompt `.save()`, `template_path`,
   `suffix_path`, `prefix_path`, `examples`, `example_prompt_path`, uploaded
   prompt configs, workflow prompt configs, plugin prompt configs, and API
   endpoints that import prompt definitions.
4. Classify each prompt config source as trusted developer-authored,
   repository-owned, admin-authored, tenant-authored, plugin-authored,
   agent-authored, notebook-authored, remote API supplied, or imported from a
   third party.
5. If LangChain is absent, fixed, or used only for repository-owned prompt
   source with no legacy loader, stop with `TRIAGE.md` listing checked files,
   resolved versions, and exposure rationale.
6. Upgrade all controlled `langchain-core` references to `1.2.22+`. Refresh
   locks, constraints, images, generated dependency reports, SBOMs, and docs.
7. Replace legacy prompt config loading for untrusted input:
   - migrate to `langchain_core.load` APIs where compatible;
   - allow only approved prompt object types;
   - reject path-bearing config keys from untrusted sources;
   - require repository-owned prompt roots for any remaining file import;
   - canonicalize final paths after joins and reject absolute paths,
     traversal, and symlink escapes;
   - keep prompt import authorization and audit logging.
8. Add safe regression checks:
   - dependency policy rejects `langchain-core <1.2.22`;
   - untrusted prompt config cannot set `template_path`, `suffix_path`,
     `prefix_path`, `examples`, or `example_prompt_path` outside the allowed
     prompt root;
   - local temporary fixtures prove rejection without reading sensitive files;
   - logs and test output do not include prompt bodies, tokens, credentials,
     or tenant content.
9. Add a PR body section named `CVE-2026-34070 operator actions` that states:
   - LangChain and `langchain-core` versions before and after;
   - which services import prompt configs;
   - which prompt config sources are trusted versus untrusted;
   - whether legacy loaders were removed or fenced;
   - which prompt roots are allowed;
   - whether logs, prompt artifacts, or uploaded configs need disclosure
     review;
   - which validation commands passed.
10. Run available validation: dependency install, lockfile integrity, unit
    tests, prompt import tests, lint/typecheck, image build, SBOM refresh,
    dependency/security scans, and non-secret service smoke checks.
11. Use PR title:
    `fix(sec): remediate CVE-2026-34070 in LangChain prompt loading`.

## Stop conditions

- No affected LangChain runtime, dependency, prompt config importer, uploaded
  prompt path, generated artifact, or deployment image is controlled by this
  repository.
- The affected LangChain service is owned by another team; name the owner and
  required fixed version in `TRIAGE.md`.
- A fixed `langchain-core` version requires a broader LangChain migration the
  agent cannot safely complete.
- Verification would require reading real secrets, prompt logs, customer files,
  cloud config, home directories, or production-mounted paths.
- Validation fails for unrelated pre-existing reasons; document those failures
  instead of broadening scope.

Output contract

  • A reviewer-ready PR or change request that upgrades langchain-core, fences or removes legacy prompt loaders for untrusted inputs, adds path-containment tests, and documents disclosure/operator review.
  • Or a TRIAGE.md file that lists inspected dependencies/importers, owner, observed version, prompt-config source boundary, allowed prompt roots, required fix, and residual risk.
  • The output must include exact validation commands and must not read real secrets, print prompt bodies, expose customer files, or log sensitive paths while validating.

Verification - what the reviewer looks for

  • No controlled manifest, lockfile, image, SBOM, or generated report resolves langchain-core <1.2.22.
  • Untrusted prompt config import paths no longer use the legacy loaders or are fenced to a canonical repository-owned prompt root.
  • Regression tests prove unsafe path-bearing prompt config keys are rejected without reading sensitive files.
  • Prompt config import authorization, provenance, and audit logging are preserved.
  • Operator notes identify any logs, prompt artifacts, or uploaded configs that need disclosure review.

Watch for

  • Updating the main requirements file while notebook, worker, evaluation, or low-code builder images still pin the vulnerable transitive dependency.
  • Treating authenticated tenant/admin prompt authors as trusted developers.
  • Blocking only template_path while examples or example_prompt_path can still load JSON or YAML outside the prompt root.
  • Replacing traversal with a brittle string prefix check that fails on symlinks or platform path differences.
  • Logging prompt config contents or file paths that include secrets while adding diagnostics.

References