Skip to content

Sanitize dsID before interpolating into file paths#126

Merged
nkcoder merged 1 commit into
mainfrom
bug/117-sanitize-dsid-paths
Jul 3, 2026
Merged

Sanitize dsID before interpolating into file paths#126
nkcoder merged 1 commit into
mainfrom
bug/117-sanitize-dsid-paths

Conversation

@nkcoder

@nkcoder nkcoder commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Closes #117.

What changed

Saved-query filenames were already guarded against path separators, but dsID was interpolated straight into filepath.Join(...) for the cache, history, and queries paths. dsID is app-generated (Date.now() timestamps) today, but a malformed or imported config with a dsID containing ../ could escape ~/.snowy.

Added a shared validateDsID (charset allowlist ^[A-Za-z0-9_-]+$) and call it at the three path-builder choke points every operation funnels through:

  • metadataCachePath — cache load/save
  • historyFile — history record/read
  • queriesDir — all saved-query ops (save/list/load/delete/rename)

The allowlist admits every real ID (timestamps, the literal default, UUID-style with hyphens) and rejects .., /, \, ., whitespace, null bytes, and empty.

Acceptance criteria

  • dsID is validated before use in any filesystem path (cache, history, queries)
  • A dsID containing path traversal or separators is rejected, with a test
  • Existing behavior for valid IDs unchanged

Testing

  • dsid_test.go: table-driven validateDsID (valid + malicious inputs) and a boundary test asserting SaveMetadataCache / RecordHistory / SaveQuery all reject ../escaped and that no file is created outside ~/.snowy.
  • go test . — full suite green (the pre-existing filename-guard test still passes).

Saved-query filenames were guarded against path separators, but dsID
was interpolated straight into filepath.Join for the cache, history,
and queries paths. dsID is app-generated today, but a malformed or
imported config with a dsID containing '../' could escape ~/.snowy.

Add validateDsID (charset allowlist ^[A-Za-z0-9_-]+$) and call it at
the three path-builder choke points: metadataCachePath, historyFile,
and queriesDir. Valid IDs (timestamps, 'default', UUIDs) are unchanged.

Closes #117
@nkcoder nkcoder merged commit a34b317 into main Jul 3, 2026
2 checks passed
@nkcoder nkcoder deleted the bug/117-sanitize-dsid-paths branch July 3, 2026 10:24
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.

Sanitize dsID before interpolating into file paths

1 participant