Skip to content

Commit 8d23cbe

Browse files
Reject path traversal
1 parent 0dbe609 commit 8d23cbe

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

src/lib/profile/storage.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ export function ensureProfilesDir(): void {
1717
}
1818

1919
export function getProfilePath(name: string): string {
20+
// Reject path traversal attempts, empty names, or names with path separators
21+
if (!name || name.includes('/') || name.includes('\\') || name.includes('..')) {
22+
throw new Error(`Invalid profile name: "${name}". Profile names cannot contain path separators or parent directory references.`)
23+
}
24+
2025
return join(getProfilesDir(), `${name}.json`)
2126
}
2227

test/commands/profiles/storage.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,38 @@ describe('profile storage', () => {
222222
expect(profileExists('nonexistent')).toBe(false)
223223
})
224224
})
225+
226+
describe('getProfilePath', () => {
227+
it('accepts valid profile names', () => {
228+
expect(() => getProfilePath('valid-profile')).not.toThrow()
229+
expect(() => getProfilePath('profile_123')).not.toThrow()
230+
expect(() => getProfilePath('MyProfile')).not.toThrow()
231+
})
232+
233+
it('rejects empty profile names', () => {
234+
expect(() => getProfilePath('')).toThrow('Invalid profile name')
235+
})
236+
237+
it('rejects profile names with forward slashes', () => {
238+
expect(() => getProfilePath('foo/bar')).toThrow('Invalid profile name')
239+
expect(() => getProfilePath('/etc/passwd')).toThrow('Invalid profile name')
240+
})
241+
242+
it('rejects profile names with backslashes', () => {
243+
expect(() => getProfilePath(String.raw`foo\bar`)).toThrow('Invalid profile name')
244+
expect(() => getProfilePath(String.raw`C:\Windows\System32`)).toThrow('Invalid profile name')
245+
})
246+
247+
it('rejects profile names with parent directory references', () => {
248+
expect(() => getProfilePath('..')).toThrow('Invalid profile name')
249+
expect(() => getProfilePath('../../etc/passwd')).toThrow('Invalid profile name')
250+
expect(() => getProfilePath('foo..bar')).toThrow('Invalid profile name')
251+
})
252+
253+
it('rejects path traversal attempts', () => {
254+
expect(() => getProfilePath('../../../../some-place-you-should-not-have-access-to')).toThrow(
255+
'Invalid profile name',
256+
)
257+
})
258+
})
225259
})

0 commit comments

Comments
 (0)