Skip to content

fix(langchain): handle NextJS catch-all route files in path validation#34969

Open
saakshigupta2002 wants to merge 10 commits intolangchain-ai:masterfrom
saakshigupta2002:fix/path-traversal-nextjs-false-positive
Open

fix(langchain): handle NextJS catch-all route files in path validation#34969
saakshigupta2002 wants to merge 10 commits intolangchain-ai:masterfrom
saakshigupta2002:fix/path-traversal-nextjs-false-positive

Conversation

@saakshigupta2002
Copy link
Contributor

Pull Request: Fix Path Traversal False Positive on NextJS Files

Summary

This PR fixes a bug where the path traversal detection in FilesystemFileSearchMiddleware and _validate_path incorrectly flagged legitimate files containing ... (triple dots) as path traversal attempts.

Fixes #34961

Problem

NextJS uses the [...slug].ts syntax for catch-all dynamic routes. When using LangChain's file system middleware with a NextJS project, files like [...nextauth].ts were incorrectly blocked with a "Path traversal not allowed" error.

Root Cause

The path validation logic used a simple substring check:

if ".." in path or "~" in path:
    raise ValueError("Path traversal not allowed")

This incorrectly matched any path containing .., including:

  • [...nextauth].ts (NextJS catch-all route)
  • spread...example.ts (file with triple dots)
  • ...special/ (directory with triple dots)

Solution

Changed the substring check to a regex pattern that only matches .. as a complete path segment:

_PATH_TRAVERSAL_PATTERN = re.compile(r"(^|[/\\])\.\.([/\\]|$)")

if _PATH_TRAVERSAL_PATTERN.search(path) or "~" in path:
    raise ValueError("Path traversal not allowed")

This pattern:

  • Allows: [...nextauth].ts, ...spread.ts, file...name.py
  • Blocks: ../secret, /.., foo/../bar, .., ..\windows

Changes

Modified Files

  1. libs/langchain_v1/langchain/agents/middleware/file_search.py

    • Added _PATH_TRAVERSAL_PATTERN regex constant
    • Updated _validate_and_resolve_path() to use regex pattern
  2. libs/partners/anthropic/langchain_anthropic/middleware/anthropic_tools.py

    • Added re import and _PATH_TRAVERSAL_PATTERN constant
    • Updated _validate_path() to use regex pattern

New Tests

  1. libs/langchain_v1/tests/unit_tests/agents/middleware/implementations/test_file_search.py

    • test_nextjs_catchall_route_files_allowed: Verifies NextJS catch-all routes work
    • test_triple_dots_in_filename_allowed: Verifies files with ... in name work
    • test_triple_dots_in_path_allowed: Verifies directories with ... work
  2. libs/partners/anthropic/tests/unit_tests/middleware/test_anthropic_tools.py

    • test_nextjs_catchall_route_paths_allowed: Verifies path validation allows ...

Test Plan

  • All existing path traversal security tests pass (ensures no security regression)
  • New tests for NextJS-style files pass
  • Verified the fix with actual NextJS file patterns

Commands to Verify

# Run file_search tests
cd libs/langchain_v1
uv run pytest tests/unit_tests/agents/middleware/implementations/test_file_search.py -v

# Run anthropic middleware tests
cd libs/partners/anthropic
uv run pytest tests/unit_tests/middleware/test_anthropic_tools.py -v

Security Considerations

  • The fix maintains the existing defense-in-depth approach
  • The relative_to() check still validates resolved paths are within the root directory
  • Path traversal with actual .. segments (like ../, /.., foo/../bar) is still blocked
  • All existing security tests continue to pass

Backward Compatibility

This is a non-breaking bug fix. The change only allows previously incorrectly blocked paths while maintaining security for actual path traversal attempts.

…ages

When all messages are removed from a thread using RemoveMessage(id=REMOVE_ALL_MESSAGES),
the agent state may contain no AIMessage. Previously, _fetch_last_ai_and_tool_messages
assumed an AIMessage always exists, causing UnboundLocalError on last_ai_index.

This change returns a synthetic AIMessage with empty content and no tool calls,
along with an empty tool message list, when no AIMessage is present. This ensures
the agent loop exits cleanly (since len(last_ai_message.tool_calls) == 0).

Fixes langchain-ai#34792
@github-actions github-actions bot added external integration PR made that is related to a provider partner package integration langchain `langchain` package issues & PRs anthropic `langchain-anthropic` package issues & PRs fix For PRs that implement a fix and removed external labels Feb 2, 2026
@codspeed-hq
Copy link

codspeed-hq bot commented Feb 2, 2026

Merging this PR will not alter performance

✅ 3 untouched benchmarks
⏩ 31 skipped benchmarks1


Comparing saakshigupta2002:fix/path-traversal-nextjs-false-positive (c53ddd6) with master (3aca3fb)

Open in CodSpeed

Footnotes

  1. 31 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@saakshigupta2002 saakshigupta2002 force-pushed the fix/path-traversal-nextjs-false-positive branch from 0b2ce74 to 434da81 Compare February 2, 2026 00:40
The path traversal check incorrectly flagged files like [...]nextauth].ts
because "..." contains "..". Changed the check to only match ".." as a
complete path segment (e.g., ../, /.., \..) rather than any occurrence
of ".." in the path string.

This fix applies to both:
- FilesystemFileSearchMiddleware in langchain
- _validate_path helper in langchain-anthropic

Fixes langchain-ai#34961
@saakshigupta2002 saakshigupta2002 force-pushed the fix/path-traversal-nextjs-false-positive branch from 74c5ee8 to 5f23574 Compare February 2, 2026 00:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

anthropic `langchain-anthropic` package issues & PRs fix For PRs that implement a fix integration PR made that is related to a provider partner package integration langchain `langchain` package issues & PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FileSystemBackend path traveseral on NextJS files

1 participant