Skip to content

Commit 3c754bd

Browse files
authored
fix(server): resolve path traversal in get-code API (EPMSPRT-2535) (#3088)
- Resolve paths under app/src/docs/_examples via path.relative check - Reject absolute and out-of-root paths - Fix GitHub URL when path is a string (avoid spread on string)
1 parent 1790735 commit 3c754bd

1 file changed

Lines changed: 22 additions & 6 deletions

File tree

server/api/getCode.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,34 @@ import { highlightTsCode } from './prism';
55

66
const router = express.Router();
77

8+
const EXAMPLES_ROOT = path.resolve(__dirname, '../../../app/src/docs/_examples');
9+
10+
function resolveSafeExamplePath(userPath: unknown): string | null {
11+
if (typeof userPath !== 'string' || userPath.length === 0) {
12+
return null;
13+
}
14+
if (path.isAbsolute(userPath)) {
15+
return null;
16+
}
17+
const resolved = path.resolve(EXAMPLES_ROOT, userPath);
18+
const relative = path.relative(EXAMPLES_ROOT, resolved);
19+
if (relative.startsWith('..') || path.isAbsolute(relative)) {
20+
return null;
21+
}
22+
return resolved;
23+
}
24+
825
router.post('/get-code', async (req: any, res: any) => {
926
try {
1027
const params = req.body;
11-
const filePath = path.resolve(__dirname, '../../../app/src/docs/_examples/', path.normalize(params.path));
12-
13-
const isPathInsideSrcDirectory = filePath.includes(path.normalize('/app/src/'));
28+
const filePath = resolveSafeExamplePath(params?.path);
1429

15-
if (!isPathInsideSrcDirectory) {
16-
return res.status(500).json({ error: `path ${filePath} is not inside docs examples folder)}` });
30+
if (!filePath) {
31+
return res.status(500).json({ error: 'path is not inside docs examples folder' });
1732
}
1833

19-
const gitUrl = 'https://github.com/epam/UUI/tree/develop' + path.join(...params.path).replace('\\', '/');
34+
const gitPath = String(params.path).replace(/\\/g, '/').replace(/^\/+/, '');
35+
const gitUrl = `https://github.com/epam/UUI/tree/develop/${gitPath}`;
2036

2137
const raw = await fs.readFile(filePath, 'utf8');
2238
const highlighted = highlightTsCode(raw);

0 commit comments

Comments
 (0)