Skip to content

fix(security): prevent path traversal in skill_view#242

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

fix(security): prevent path traversal in skill_view#242
Bartok9 wants to merge 1 commit into
NousResearch:mainfrom
Bartok9:fix/path-traversal-skill-view-220

Conversation

@Bartok9

@Bartok9 Bartok9 commented Mar 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #220

skill_view() accepted a file_path parameter without validating for path traversal. An LLM or prompt injection could read arbitrary files including ~/.hermes/.env (API keys) or ~/.ssh/id_rsa.

Changes

  • Add .. component check matching existing skill_manager_tool.py pattern
  • Add resolve() containment check as defense in depth
  • Return structured JSON errors for blocked paths
  • Add comprehensive test coverage in tests/tools/test_skills_tool_path_traversal.py

Security

The fix uses two layers of protection:

  1. Component check: Reject any path containing .. in its parts
  2. Boundary check: Verify resolved path is within skill directory

This prevents both direct traversal (../../.env) and symlink-based escapes.

Testing

# Before fix - reads ~/.hermes/.env
skill_view("any-skill", file_path="../../.env")

# After fix - returns error
{"success": false, "error": "Path traversal ('..') is not allowed."}

Related

Matches the existing validation pattern in skill_manager_tool.py lines 177-178.

Fixes NousResearch#220

skill_view() accepted a file_path parameter without validating for
path traversal. An LLM or prompt injection could read arbitrary files
including ~/.hermes/.env (API keys) or ~/.ssh/id_rsa.

Changes:
- Add '..' component check matching skill_manager_tool.py pattern
- Add resolve() containment check as defense in depth
- Return structured JSON errors for blocked paths
- Add comprehensive test coverage

The fix uses two layers of protection:
1. Reject any path containing '..' in its components
2. Verify resolved path is within skill directory boundary

This prevents both direct traversal (../../.env) and symlink-based
escapes.
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
Contributor

Thanks @Bartok9! Your code fix was the most robust — the trailing / in the startswith() check and the exception handling on resolve() were great catches.

The tests needed a small adjustment — they mocked _find_all_skills but skill_view looks up skills via SKILLS_DIR directly. We rewrote them to mock SKILLS_DIR instead and kept your edge cases (symlink escape).

Fixed in commit 1cb2311 with credit to you.

@teknium1 teknium1 closed this Mar 2, 2026
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
olympus-terminal pushed a commit to olympus-terminal/hermes-agent that referenced this pull request May 16, 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
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request Jun 10, 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

2 participants