Skip to content

Commit 492c76e

Browse files
committed
resolved copilot suggestion issue
1 parent 8e6c55c commit 492c76e

File tree

3 files changed

+47
-62
lines changed

3 files changed

+47
-62
lines changed

api/src/services/runCli.service.ts

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,50 +18,6 @@ interface TestStack {
1818
}
1919
import utilitiesHandler from '@contentstack/cli-utilities';
2020

21-
/**
22-
* Adds a custom message to the CLI logs file
23-
* @param loggerPath - Path to the log file
24-
* @param level - Log level (default: 'info')
25-
* @param message - Message to be logged
26-
*/
27-
const addCustomMessageInCliLogs = async (
28-
loggerPath: string,
29-
level: string = 'info',
30-
message: string
31-
) => {
32-
try {
33-
const logEntry = {
34-
level,
35-
message,
36-
timestamp: new Date().toISOString(),
37-
};
38-
39-
// Create directory if it doesn't exist
40-
const logDir = path.dirname(loggerPath);
41-
await fs.promises.mkdir(logDir, { recursive: true });
42-
43-
// Append log with proper formatting
44-
await fs.promises.appendFile(
45-
loggerPath,
46-
JSON.stringify(logEntry, null, 2) + '\n'
47-
);
48-
49-
// Also log to console based on level
50-
switch (level) {
51-
case 'error':
52-
console.error(message);
53-
break;
54-
case 'warn':
55-
console.warn(message);
56-
break;
57-
default:
58-
console.info(message);
59-
}
60-
} catch (error) {
61-
console.error('Error writing to log file:', error);
62-
}
63-
};
64-
6521
/**
6622
* Determines log level based on message content without removing ANSI codes
6723
*/
@@ -190,11 +146,6 @@ export const runCli = async (
190146
transformePath: string
191147
) => {
192148
try {
193-
// Set appropriate completion message based on migration type
194-
const message = isTest
195-
? 'Test Migration Process Completed'
196-
: 'Migration Process Completed';
197-
198149
// Format region string for CLI compatibility
199150
const regionPresent =
200151
CS_REGIONS.find((item) => item === rg) ?? 'NA'.replace(/_/g, '-');

api/src/utils/custom-logger.utils.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,33 @@ import logger from './logger.js';
55
import { getSafePath } from './sanitize-path.utils.js';
66

77
// Utility function to safely join and resolve paths
8-
const safeJoin = (basePath: string, ...paths: string[]) => {
9-
const resolvedPath = getSafePath(path.resolve(basePath, ...paths)); // Resolve absolute path
10-
if (!resolvedPath.startsWith(basePath)) {
11-
throw new Error('Invalid file path');
8+
/**
9+
* Safely joins and resolves paths to prevent directory traversal attacks
10+
* @param basePath - Base directory that should contain the result
11+
* @param paths - Path segments to join with the base path
12+
* @returns A safe absolute path guaranteed to be within basePath
13+
*/
14+
const safeJoin = (basePath: string, ...paths: string[]): string => {
15+
// Get normalized absolute base path
16+
const absoluteBasePath = path.resolve(basePath);
17+
18+
// Get sanitized absolute resolved path
19+
const resolvedPath = getSafePath(path.resolve(basePath, ...paths));
20+
21+
// Use path.relative to check containment - this is more secure
22+
const relativePath = path.relative(absoluteBasePath, resolvedPath);
23+
24+
// Check if path attempts to traverse up/outside the base directory
25+
if (
26+
relativePath === '' ||
27+
relativePath === '.' ||
28+
(!relativePath.startsWith('..') && !path.isAbsolute(relativePath))
29+
) {
30+
return resolvedPath; // Path is safely within base directory
1231
}
13-
return resolvedPath;
32+
33+
// Path is trying to escape - reject it
34+
throw new Error('Invalid file path: Directory traversal attempt detected');
1435
};
1536

1637
const fileExists = async (path: string): Promise<boolean> => {

api/src/utils/sanitize-path.utils.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import path from "path";
1+
import path from 'path';
22

33
/**
44
* Sanitizes a filename by removing unsafe characters.
@@ -8,7 +8,7 @@ import path from "path";
88
* @returns A safe, sanitized filename.
99
*/
1010
const sanitizeFilename = (filename: string): string => {
11-
return path.basename(filename).replace(/[^a-zA-Z0-9_.\s-]/g, "");
11+
return path.basename(filename).replace(/[^a-zA-Z0-9_.\s-]/g, '');
1212
};
1313

1414
/**
@@ -22,7 +22,7 @@ const sanitizeFilename = (filename: string): string => {
2222
export const getSafePath = (inputPath: string, baseDir?: string): string => {
2323
try {
2424
// Resolve the absolute path (handles path.join(), path.resolve(), and full paths)
25-
const resolvedPath = path.resolve(baseDir || "", inputPath);
25+
const resolvedPath = path.resolve(baseDir || '', inputPath);
2626

2727
// Ensure only the last segment (filename) is sanitized
2828
const dirPath = path.dirname(resolvedPath);
@@ -34,15 +34,28 @@ export const getSafePath = (inputPath: string, baseDir?: string): string => {
3434
// Ensure the path remains inside baseDir (if provided)
3535
if (baseDir) {
3636
const safeBaseDir = path.resolve(baseDir);
37-
if (!safePath.startsWith(safeBaseDir)) {
38-
console.warn("Invalid file path detected, using default safe path.");
39-
return path.join(safeBaseDir, "default.log");
37+
38+
// Use path.relative to securely check path containment
39+
const relativePath = path.relative(safeBaseDir, safePath);
40+
41+
// If relativePath starts with '..' or is absolute, it's trying to escape
42+
if (
43+
relativePath === '' ||
44+
relativePath === '.' ||
45+
(!relativePath.startsWith('..') && !path.isAbsolute(relativePath))
46+
) {
47+
// Path is safely within the base directory
48+
return safePath;
49+
} else {
50+
// Path is trying to escape the base directory
51+
console.warn('Invalid file path detected, using default safe path.');
52+
return path.join(safeBaseDir, 'default.log');
4053
}
4154
}
4255

4356
return safePath;
4457
} catch (error) {
45-
console.error("Error generating safe path:", error);
46-
return baseDir ? path.join(baseDir, "default.log") : "default.log";
58+
console.error('Error generating safe path:', error);
59+
return baseDir ? path.join(baseDir, 'default.log') : 'default.log';
4760
}
4861
};

0 commit comments

Comments
 (0)