Skip to content

Security fixes: path traversal, filename injection, input validation, error leakage#204

Draft
Copilot wants to merge 25 commits intodevelopmentfrom
copilot/review-project
Draft

Security fixes: path traversal, filename injection, input validation, error leakage#204
Copilot wants to merge 25 commits intodevelopmentfrom
copilot/review-project

Conversation

Copy link

Copilot AI commented Mar 19, 2026

Several security and correctness issues found across the API servers during project review.

screens/images — Path Traversal & Filename Injection

  • Replaced all path.includes("..") guards with resolveSafePath() using path.resolve() + prefix check against basePath. The old check is bypassable via encoded sequences, symlinks, or null bytes.
  • Added sanitizeFileName() using path.basename() + null-byte stripping on uploaded filenames. A filename like ../../etc/cron.d/evil would previously write outside the upload root.

screens/screenManager — Input Validation & Error Leakage

  • PUT /api/screens/:screenId now validates req.body with isDbScreen() before spreading into the Prisma upsert — consistent with how POST /api/screens already handles this.
  • /api/screens/resolve was sending `Internal server error: ${error}` to clients. Now logs server-side and returns a generic message.
  • Removed redundant res.end() calls after res.send() in /next and /previous handlers.

ranges/merge — Body Parsing & Crash on Malformed Input

  • Added missing express.json() middleware. The server had no body parser, so parseInt(req.body) in POST /api/ranges/known/:rangeMac always returned NaN — the endpoint was effectively broken.
  • Fixed the parse: parseInt(req.body)parseInt(req.body?.rangeId).
  • Wrapped JSON.parse(handshakeRanges) in try-catch; malformed JSON in the WebSocket handshake query previously threw an uncaught exception.
Original prompt

Please review this project?


⚡ Quickly spin up Copilot coding agent tasks from anywhere on your macOS or Windows machine with Raycast.

Copilot AI changed the title [WIP] Review project for feedback and improvements Security fixes: path traversal, filename injection, input validation, error leakage Mar 19, 2026
Copilot AI requested a review from SvenFinn March 19, 2026 17:47
Comment on lines -10 to +31
const basePath = `/app/files`;
const basePath = nodePath.resolve(`/app/files`);

/**
* Resolves a user-supplied path relative to basePath and verifies it stays
* within basePath. Returns null if the resolved path would escape basePath.
*/
function resolveSafePath(userInput: string): string | null {
const resolved = nodePath.resolve(basePath, userInput);
if (resolved !== basePath && !resolved.startsWith(basePath + nodePath.sep)) {
return null;
}
return resolved;
}

/**
* Sanitizes a filename by removing path separators, null bytes, and other
* characters that could be used for path traversal or injection attacks.
*/
function sanitizeFileName(name: string): string {
return nodePath.basename(name).replace(/[\0]/g, '_');
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sanitization should propably be applied to screens/evaluations also, and be separated into its own lib, maybe also containing the response types for these routes

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooh, also, do there exist any libs that do this already? So I don't need to maintain it myself?

import { isStartList } from 'dc-ranges-types';

const app: Express = express();
app.use(express.json());
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this here?
What does it do?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants