Skip to content

fix(server): confine state reads to the .ai-engineering directory - #14

Merged
BoozeLee merged 1 commit into
mainfrom
fix/server-path-containment
Oct 13, 2026
Merged

BoozeLee merged 1 commit into
mainfrom
fix/server-path-containment

Conversation

@BoozeLee

Copy link
Copy Markdown
Collaborator

Closes code-scanning alert #3 (py/path-injection, harness/policy.py:57).

Assessment: not exploitable today: every route validates names with NAME_RE (no '/'), the POST body uses the same validator, and the server is loopback-only with a bearer token. CodeQL cannot see a regex check in another function as a sanitizer.

Change: the server's _jload resolves the path with os.path.realpath (symlinks included) and returns 400 unless it is inside .ai-engineering. All server reads go through it.

Test: test_state_reads_are_confined_to_the_state_directory (written first, seen failing): '..' escapes and a planted symlink are refused.

Local (codespace, missing uv/ruff/PyYAML): 64 passed / 11 failed with the change vs 63 / 11 without; the 11 are the same environment failures (verify runs, test_ci). Full results: this PR's CI.

🤖 Generated with Claude Code

CodeQL flagged py/path-injection where jload reads a path built from a
request. Every route already limits names to NAME_RE, which has no
'/', so no request can reach outside today; CodeQL cannot see a regex
check in another function. The server's _jload now resolves the path
(symlinks included) and refuses anything outside the state directory,
as a second wall and a guard CodeQL can follow. New test covers
'..' escapes and a planted symlink.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@BoozeLee
BoozeLee merged commit e459e53 into main Oct 13, 2026
6 checks passed
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