2
0
mirror of https://github.com/tenrok/axios.git synced 2026-06-23 20:40:40 +03:00

feat: enhance pipeFileToResponse with error handling (#7169)

* Enhance pipeFileToResponse with error handling

Added error handling for file streaming in pipeFileToResponse function.

* Security: Fix path traversal vulnerability in pipeFileToResponse with input validation and error handling

Security: Enhance file streaming with comprehensive path validation

- Add path traversal protection in pipeFileToResponse function
- Implement input validation to prevent directory traversal attacks
- Improve error handling for file read operations with proper status codes
- Ensure resolved paths stay within intended directory boundaries
- Add security checks using path.resolve() and startsWith() methods
- Fix CodeQL "Uncontrolled data in path expression" vulnerability
- Maintain backward compatibility while enhancing security

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
This commit is contained in:
Anchal Singh
2025-12-05 12:42:15 +05:30
committed by GitHub
parent 86b2423597
commit 88d7884254
+51 -7
View File
@@ -3,6 +3,7 @@ import path from 'path';
import http from 'http'; import http from 'http';
import minimist from 'minimist'; import minimist from 'minimist';
import url from "url"; import url from "url";
const argv = minimist(process.argv.slice(2)); const argv = minimist(process.argv.slice(2));
let server; let server;
let dirs; let dirs;
@@ -67,14 +68,52 @@ function send404(res, body) {
} }
function pipeFileToResponse(res, file, type) { function pipeFileToResponse(res, file, type) {
if (type) { try {
res.writeHead(200, { // Validate file path - prevent directory traversal
'Content-Type': type const safeBasePath = path.join(__dirname, 'examples');
}); const resolvedPath = path.resolve(path.join(safeBasePath, file));
}
fs.createReadStream(path.join(__dirname, file)).pipe(res);
}
// Ensure the resolved path is within intended directory
if (!resolvedPath.startsWith(safeBasePath)) {
res.writeHead(400);
res.end('Invalid file path');
return;
}
// Check if file exists
if (!fs.existsSync(resolvedPath)) {
res.writeHead(404);
res.end('File not found');
return;
}
if (type) {
res.writeHead(200, {
"Content-Type": type
});
} else {
res.writeHead(200);
}
const stream = fs.createReadStream(resolvedPath);
stream.on("error", (err) => {
console.error("Error while reading file:", err.message);
if (!res.headersSent) {
res.writeHead(500, { "Content-Type": "text/plain" });
}
res.end("File read error");
});
stream.pipe(res);
} catch (err) {
console.error("Unexpected error:", err.message);
if (!res.headersSent) {
res.writeHead(500, { "Content-Type": "text/plain" });
}
res.end("Internal server error");
}
}
dirs = listDirs(__dirname); dirs = listDirs(__dirname);
@@ -123,6 +162,7 @@ server = http.createServer(function (req, res) {
} else { } else {
send404(res); send404(res);
} }
return;
} }
// Process server request // Process server request
@@ -130,10 +170,14 @@ server = http.createServer(function (req, res) {
if (fs.existsSync(path.join(__dirname, url + '.js'))) { if (fs.existsSync(path.join(__dirname, url + '.js'))) {
import('file://' + path.join(__dirname, url + '.js')).then((server) => { import('file://' + path.join(__dirname, url + '.js')).then((server) => {
server.default(req, res); server.default(req, res);
}).catch(err => {
console.error('Error importing server:', err);
send404(res);
}); });
} else { } else {
send404(res); send404(res);
} }
return;
} }
else { else {
send404(res); send404(res);