another test
This commit is contained in:
@@ -3669,11 +3669,18 @@ function handlePeerData(data, topicId, peer) {
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn(`[WARN] Unhandled response type: ${response.type}`);
|
||||
// Check if this is a directory browser response (no type field, but has contents)
|
||||
if (response.success && Array.isArray(response.contents) && response.path !== undefined) {
|
||||
// This is a directory browser response, let the directory handler process it
|
||||
// Don't warn about it
|
||||
} else {
|
||||
console.warn(`[WARN] Unhandled response type: ${response.type}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle peer response callback if defined
|
||||
// This allows custom handlers (like directory browser) to process responses
|
||||
if (typeof window.handlePeerResponse === 'function') {
|
||||
window.handlePeerResponse(response);
|
||||
}
|
||||
|
||||
+22
-6
@@ -1291,22 +1291,38 @@ swarm.on('connection', (peer) => {
|
||||
console.log(`[INFO] Handling 'browseDirectory' command for path: ${parsedData.args?.path || '/'}`);
|
||||
try {
|
||||
const requestedPath = parsedData.args?.path || '/';
|
||||
console.log(`[DEBUG] Requested path: ${requestedPath}`);
|
||||
console.log(`[DEBUG] Requested path: "${requestedPath}"`);
|
||||
|
||||
// Validate and sanitize path
|
||||
// Validate path
|
||||
if (!validation.isValidDirectoryPath(requestedPath)) {
|
||||
console.error(`[ERROR] Invalid directory path: ${requestedPath}`);
|
||||
throw new Error('Invalid directory path');
|
||||
}
|
||||
|
||||
// Sanitize path
|
||||
const safePath = validation.sanitizeDirectoryPath(requestedPath);
|
||||
console.log(`[DEBUG] Sanitized path: ${safePath}`);
|
||||
console.log(`[DEBUG] Sanitized path: "${safePath}" (from "${requestedPath}")`);
|
||||
|
||||
// Verify the path exists and is a directory
|
||||
try {
|
||||
const stats = fs.statSync(safePath);
|
||||
if (!stats.isDirectory()) {
|
||||
throw new Error('Not a directory: The specified path is not a directory');
|
||||
}
|
||||
} catch (statError) {
|
||||
if (statError.code === 'ENOENT') {
|
||||
throw new Error('Directory not found: The specified path does not exist');
|
||||
} else if (statError.code === 'EACCES') {
|
||||
throw new Error('Permission denied: You do not have permission to access this directory');
|
||||
}
|
||||
throw statError;
|
||||
}
|
||||
|
||||
// Read directory contents
|
||||
const contents = [];
|
||||
try {
|
||||
const items = fs.readdirSync(safePath, { withFileTypes: true });
|
||||
console.log(`[DEBUG] Found ${items.length} items in directory`);
|
||||
console.log(`[DEBUG] Found ${items.length} items in directory "${safePath}"`);
|
||||
|
||||
for (const item of items) {
|
||||
try {
|
||||
@@ -1326,10 +1342,10 @@ swarm.on('connection', (peer) => {
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[DEBUG] Returning ${contents.length} items to client`);
|
||||
console.log(`[DEBUG] Returning ${contents.length} items to client for path: "${safePath}"`);
|
||||
response = { success: true, contents, path: safePath };
|
||||
} catch (readError) {
|
||||
console.error(`[ERROR] Failed to read directory ${safePath}:`, readError);
|
||||
console.error(`[ERROR] Failed to read directory "${safePath}":`, readError);
|
||||
if (readError.code === 'EACCES') {
|
||||
throw new Error('Permission denied: You do not have permission to access this directory');
|
||||
} else if (readError.code === 'ENOENT') {
|
||||
|
||||
@@ -351,20 +351,33 @@ function isValidDirectoryPath(path) {
|
||||
* @param {string} path - Directory path
|
||||
* @returns {string} - Sanitized path
|
||||
*/
|
||||
function sanitizeDirectoryPath(path) {
|
||||
if (!path || typeof path !== 'string') return '/';
|
||||
function sanitizeDirectoryPath(inputPath) {
|
||||
if (!inputPath || typeof inputPath !== 'string') {
|
||||
console.warn('[WARN] sanitizeDirectoryPath: Invalid input, returning /');
|
||||
return '/';
|
||||
}
|
||||
|
||||
// Remove null bytes and control characters
|
||||
let sanitized = path.replace(/[\x00-\x1F\x7F]/g, '').trim();
|
||||
let sanitized = inputPath.replace(/[\x00-\x1F\x7F]/g, '').trim();
|
||||
|
||||
// If empty after cleaning, return root
|
||||
if (!sanitized) {
|
||||
console.warn('[WARN] sanitizeDirectoryPath: Empty after cleaning, returning /');
|
||||
return '/';
|
||||
}
|
||||
|
||||
// Resolve to absolute path and prevent traversal
|
||||
try {
|
||||
// Resolve the path to handle relative components safely
|
||||
// If already absolute, use as-is (path.resolve will normalize it)
|
||||
// If relative, resolve from current working directory
|
||||
sanitized = path.resolve(sanitized);
|
||||
|
||||
console.log(`[DEBUG] sanitizeDirectoryPath: Resolved "${inputPath}" to "${sanitized}"`);
|
||||
|
||||
// Ensure it's still absolute after resolution
|
||||
if (!path.isAbsolute(sanitized)) {
|
||||
sanitized = '/';
|
||||
console.warn(`[WARN] sanitizeDirectoryPath: Resolved path is not absolute: "${sanitized}", returning /`);
|
||||
return '/';
|
||||
}
|
||||
|
||||
// Additional safety: prevent access to sensitive directories
|
||||
@@ -373,14 +386,17 @@ function sanitizeDirectoryPath(path) {
|
||||
for (const sensitive of sensitivePaths) {
|
||||
if (sanitized.startsWith(sensitive) && sanitized !== sensitive) {
|
||||
// Allow root level but not deeper
|
||||
console.warn(`[WARN] sanitizeDirectoryPath: Blocked access to sensitive path: "${sanitized}"`);
|
||||
return '/';
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[DEBUG] sanitizeDirectoryPath: Final sanitized path: "${sanitized}"`);
|
||||
return sanitized;
|
||||
} catch (error) {
|
||||
console.warn(`[WARN] Path sanitization error for "${inputPath}":`, error.message);
|
||||
return '/';
|
||||
}
|
||||
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
export {
|
||||
|
||||
Reference in New Issue
Block a user