mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-10 03:27:59 +00:00
fix: accept absolute analyze paths with trailing separator
Fixes abhigyanpatwari/GitNexus#587
This commit is contained in:
parent
12be2025f1
commit
7cab4b0719
2 changed files with 43 additions and 1 deletions
|
|
@ -865,12 +865,26 @@ export const createServer = async (port: number, host: string = '127.0.0.1') =>
|
|||
}
|
||||
|
||||
// Path validation: require absolute path, reject traversal (e.g. /tmp/../etc/passwd)
|
||||
// while still accepting common absolute-path variants with trailing separators.
|
||||
if (repoLocalPath) {
|
||||
if (!path.isAbsolute(repoLocalPath)) {
|
||||
res.status(400).json({ error: '"path" must be an absolute path' });
|
||||
return;
|
||||
}
|
||||
if (path.normalize(repoLocalPath) !== path.resolve(repoLocalPath)) {
|
||||
|
||||
const normalizedInput = path.normalize(repoLocalPath);
|
||||
const resolvedInput = path.resolve(repoLocalPath);
|
||||
// normalize() may keep a trailing separator (e.g. /home/user/project/)
|
||||
// while resolve() typically strips it. Compare without trailing separators
|
||||
// so valid absolute paths are accepted consistently.
|
||||
const stripTrailingSeparator = (p: string): string => {
|
||||
if (p.length <= 1) return p;
|
||||
return p.replace(/[\\/]+$/, '');
|
||||
};
|
||||
|
||||
if (
|
||||
stripTrailingSeparator(normalizedInput) !== stripTrailingSeparator(resolvedInput)
|
||||
) {
|
||||
res.status(400).json({ error: '"path" must not contain traversal sequences' });
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
28
gitnexus/test/unit/analyze-path-validation.test.ts
Normal file
28
gitnexus/test/unit/analyze-path-validation.test.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import path from 'path';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
const hasTraversalSequence = (repoLocalPath: string): boolean => {
|
||||
const normalizedInput = path.normalize(repoLocalPath);
|
||||
const resolvedInput = path.resolve(repoLocalPath);
|
||||
const stripTrailingSeparator = (p: string): string => {
|
||||
if (p.length <= 1) return p;
|
||||
return p.replace(/[\\/]+$/, '');
|
||||
};
|
||||
|
||||
return stripTrailingSeparator(normalizedInput) !== stripTrailingSeparator(resolvedInput);
|
||||
};
|
||||
|
||||
describe('analyze path validation', () => {
|
||||
it('accepts absolute paths with trailing separator', () => {
|
||||
expect(hasTraversalSequence('/home/user/project/')).toBe(false);
|
||||
expect(hasTraversalSequence('/home/user/project//')).toBe(false);
|
||||
});
|
||||
|
||||
it('accepts normalized absolute paths', () => {
|
||||
expect(hasTraversalSequence('/home/user/project')).toBe(false);
|
||||
});
|
||||
|
||||
it('rejects traversal sequences', () => {
|
||||
expect(hasTraversalSequence('/tmp/project/../other')).toBe(true);
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue