Skip to content

feat(langchain): add LC-009, LC-023 path safety rules - #59

Open
bradAGI wants to merge 1 commit into
trustabl:mainfrom
bradAGI:feat/langchain-path-safety
Open

feat(langchain): add LC-009, LC-023 path safety rules#59
bradAGI wants to merge 1 commit into
trustabl:mainfrom
bradAGI:feat/langchain-path-safety

Conversation

@bradAGI

@bradAGI bradAGI commented Aug 24, 2026

Copy link
Copy Markdown

LangChain had no path-safety rule. Claude SDK (CSDK-004/012), OpenAI (OAI-006), ADK (ADK-004), and MCP (MCP-005) all ship one. Ships the python/TypeScript pair this pack uses throughout (LC-003/011, LC-004/012, LC-005/013).

LC-009 (python). Two things make the framing LangChain's own rather than a copy of CSDK-004. The args_schema looks like it covers this and doesn't — a Pydantic field typed str or Path validates cleanly while still carrying ../../etc/passwd, because the schema constrains the argument's type, not the region of the filesystem it points at. And LangChain agents are a common indirect-injection target: a retrieved document or a page fetched mid-run can carry the path the model then passes here, so the argument is hostile even when the user isn't. The fix pushes the check onto the args_schema field as a validator so containment holds for every tool accepting that path.

Uses the per-param call_uses_unnormalized_path_param with the same callee set as CSDK-004, so a tool with two path params and one .resolve() still fires on the unresolved one.

LC-023 (typescript). Mirrors CSDK-012, including its coarse-signal caveat, stated in the explanation so the finding is honest about itself: it flags any filesystem write, not only unnormalized paths, because TS path-normalization analysis isn't wired yet. Confidence 0.5 to match. The injection route here is the ordinary one in this framework rather than an exotic case — a retrieval chain feeds fetched documents into the same context the model plans from, so text in a page or a knowledge-base record can supply the filename. The Zod schema has the same blind spot as the Python args_schema: it constrains the argument's type, not where it points.

Verification — engine built at main:

$ trustabl rules validate .
OK: 86 rule pack(s), 208 rule(s) valid under rule schema version 14
fixture findings
python, open(note_path) on a raw param LC-009, LC-201
python, Path(...).resolve() + is_relative_to root check LC-201
typescript, writeFileSync(notePath, body) LC-023, LC-201
typescript, server-derived id, no model-supplied path LC-201

(LC-201 is the pre-existing missing-AGENTS.md repo rule.)

No new predicates, so no schema_version bump.

Updated from the original single-rule version: I'd drafted LC-023 as a separate PR, then folded it in here — both rules create langchain/path_safety.yaml, so as two PRs they'd have been an add/add conflict, and "LangChain path safety" is the same atomic unit either way.

LangChain had no path-safety rule; Claude SDK (CSDK-004/012), OpenAI
(OAI-006), ADK (ADK-004), and MCP (MCP-005) all ship one. Ships the
python/TypeScript pair this pack uses throughout.

LC-009 (python): the args_schema does not close the gap — a Pydantic
field typed str or Path validates cleanly while still carrying
../../etc/passwd, because the schema constrains the argument's type and
not the region of the filesystem it points at. LangChain agents are also a
common indirect injection target: a retrieved document or a page fetched
mid-run can carry the path the model then passes in.

LC-023 (typescript): mirrors CSDK-012, including its coarse-signal caveat
— it flags any filesystem write rather than only unnormalized paths,
because TS path-normalization analysis is not yet wired.
@bradAGI
bradAGI force-pushed the feat/langchain-path-safety branch from 29aab4a to 086a9d7 Compare August 24, 2026 18:49
@bradAGI bradAGI changed the title feat(langchain): add LC-009, path parameter used in I/O without validation feat(langchain): add LC-009, LC-023 path safety rules Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant