Repository navigation
fix(storage): accept keys whose first segment starts with dots - #17
Merged
kamilmysliwiec merged 2 commits intoOct 12, 2026
Merged
Conversation
LocalDisk treated a key like `..foo/a` as a path that leaves the root.
The root check used `startsWith('..')` on the real parent directory, so
any directory named `..something` at the top level looked like a parent.
put, copy and move threw StorageInvalidKeyError, and exists, get, stat,
delete and list found nothing.
The check now refuses only `..` and `..` followed by a separator. Links
that point outside the root are still refused.
5 of 12 tasks
# Conflicts: # tests/local-disk.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: N/A
Hi! 👋
LocalDiskrefuses a valid key when its first segment starts with two dots, like..foo/a.LocalDisk.inside()(lib/disks/local.disk.ts:361) checks!rel.startsWith('..')on the path of the key's parent directory, relative to the root. For..foo/athe parent is..foo, so the check reads it as a path above the root.put,copyandmovethrowStorageInvalidKeyError("the key leads outside the disk's root through a link").existsreturnsfalse.getandstatthrow not found.deletedoes nothing. A prefixlistreturns no entries.InMemoryDiskaccepts the same keys.Repro: https://github.com/johnnyhuirilef/nestjs-repros/tree/main/storage-dotdot-prefixed-key
What is the new behavior?
inside()treats a path as outside the root only when it is..or starts with..and a path separator.put,get,stat,exists,copy,move,deleteandlistwork for keys like..foo/aand...dots/a, as they do onInMemoryDisk...segment is still invalid. A link that points outside the root, or at the parent of the root, still throwsStorageInvalidKeyError. This holds for a link named..escapetoo.Does this PR introduce a breaking change?
No. The change only accepts keys that were valid but refused.
Other information
The shared contract suite in
tests/disks.spec.tsnow runs..a,..foo/a,...dots/aanddocs/..foo/athrough put, get, exists, list, copy, move and delete on every disk.tests/local-disk.spec.tschecks that..foo/ais stored inside the root and that a link named..escapestays refused. It also checks a link to the parent of the root and a link to the internal directory.The new
..foo/acases fail onLocalDiskwithout the fix and pass with it.If you prefer a different approach or smaller tests, I am happy to change it. 🙂