Skip to content

fix(obsidian): prevent path traversal in exporter file path construction#423

Merged
Alan-TheGentleman merged 2 commits into
mainfrom
fix/obsidian-path-traversal
May 27, 2026
Merged

fix(obsidian): prevent path traversal in exporter file path construction#423
Alan-TheGentleman merged 2 commits into
mainfrom
fix/obsidian-path-traversal

Conversation

@Alan-TheGentleman

Copy link
Copy Markdown
Collaborator

Summary

internal/obsidian/exporter.go built output paths by passing *obs.Project and obs.Type directly to filepath.Join with no sanitization, allowing values like ../../etc or /etc to write files outside the intended {vault}/engram/ export root.

Adds sanitizePathComponent() which replaces path separators and .. sequences before the join, followed by a filepath.Clean + prefix containment check that rejects any path that still escapes the root. Minimal change, no behavior difference for well-formed project/type values.

Closes #180

Test plan

  • go test ./internal/obsidian/ -run TestPathTraversalPrevention -v — 6 subtests (dotdot in project/type/both, absolute path in project/type, nested traversal), all pass
  • go test ./... && go vet ./... && go build ./... — clean

Sanitize project and type path components before filepath.Join to strip
separators and dot-dot sequences, and add a post-join containment check
that rejects any resolved path escaping the vault/engram root (issue #180).
Copilot AI review requested due to automatic review settings May 27, 2026 14:43
@Alan-TheGentleman Alan-TheGentleman added the type:bug Bug fix label May 27, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the Obsidian exporter against path traversal when constructing observation export paths under {vault}/engram.

Changes:

  • Adds sanitizePathComponent() for project/type path components.
  • Applies sanitized project/type values when building observation file paths.
  • Adds traversal-prevention tests covering malicious project/type values.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
internal/obsidian/exporter.go Sanitizes observation export path components and adds containment validation.
internal/obsidian/exporter_test.go Adds security regression coverage for traversal-style project/type inputs.
internal/obsidian/testhelpers_test.go Adds test helpers for walking files and checking path containment.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +231 to +235
// Containment check: reject any path that escapes engRoot after cleaning.
cleanRoot := filepath.Clean(engRoot)
cleanPath := filepath.Clean(absPath)
if !strings.HasPrefix(cleanPath, cleanRoot+string(filepath.Separator)) {
result.Errors = append(result.Errors, fmt.Errorf("unsafe path rejected (would escape export root): %s", cleanPath))
@Alan-TheGentleman Alan-TheGentleman merged commit d0e7e21 into main May 27, 2026
5 checks passed
@Alan-TheGentleman Alan-TheGentleman deleted the fix/obsidian-path-traversal branch May 27, 2026 14:50
rubenqc added a commit to cloudopstudio/engram that referenced this pull request Jun 11, 2026
…ogramming#423, Gentleman-Programming#429, Gentleman-Programming#428, Gentleman-Programming#451, Gentleman-Programming#453)

Conflict resolution:
- schema_pg.go: RLS global-scope migration renumbered v10 -> v12 (master
  already had v10 memory_relations and v11 decay columns)
- server.go: kept GET /sessions/{id} and GET /project/current routes,
  applied requireAuth to DELETE /sessions/{id} and POST /projects/migrate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(obsidian): path traversal via unsanitized project name in Obsidian exporter

2 participants