Fixed issue that could allow deleting and uploading items outside the restricted directories.

This commit is contained in:
Jaret Burkett committed 2026-09-15 10:13:53 -06:00
1 parent 07de70940a
commit 8bf12e476e
4 files changed
+30 -7

No files matched your search

+10 -2
View File
@@ -7,8 +7,16 @@ export async function POST(request: Request) {
try {
const body = await request.json();
const { name } = body;
let datasetsPath = await getDatasetsRoot();
let datasetPath = path.join(datasetsPath, name);
if (typeof name !== 'string' || name.trim() === '') {
return NextResponse.json({ error: 'Invalid dataset name' }, { status: 400 });
}
const datasetsPath = await getDatasetsRoot();
const datasetPath = path.resolve(datasetsPath, name);
// Must resolve to a direct child of the datasets root; rejects "..", absolute paths, and the root itself.
if (path.dirname(datasetPath) !== datasetsPath || datasetPath === datasetsPath) {
return NextResponse.json({ error: 'Invalid dataset name' }, { status: 400 });
}
// if folder doesnt exist, ignore
if (!fs.existsSync(datasetPath)) {
+8 -1
View File
@@ -12,7 +12,14 @@ export async function POST(request: Request) {
const datasetsPath = await getDatasetsRoot();
const body = await request.json();
const { datasetName } = body;
const datasetFolder = path.join(datasetsPath, datasetName);
if (typeof datasetName !== 'string' || datasetName.trim() === '') {
return NextResponse.json({ error: 'Invalid dataset name' }, { status: 400 });
}
const datasetFolder = path.resolve(datasetsPath, datasetName);
// Must resolve to a direct child of the datasets root; rejects "..", absolute paths, and the root itself.
if (path.dirname(datasetFolder) !== datasetsPath || datasetFolder === datasetsPath) {
return NextResponse.json({ error: 'Invalid dataset name' }, { status: 400 });
}
try {
// Check if folder exists
+11 -3
View File
@@ -1,7 +1,7 @@
// src/app/api/datasets/upload/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { writeFile, mkdir } from 'fs/promises';
import { join } from 'path';
import path, { join } from 'path';
import { getDatasetsRoot } from '@/server/settings';
export async function POST(request: NextRequest) {
@@ -18,12 +18,20 @@ export async function POST(request: NextRequest) {
return NextResponse.json({ error: 'No files provided' }, { status: 400 });
}
if (typeof datasetName !== 'string' || datasetName.trim() === '') {
return NextResponse.json({ error: 'Invalid dataset name' }, { status: 400 });
}
const uploadDir = path.resolve(datasetsPath, datasetName);
// Must resolve to a direct child of the datasets root; rejects "..", absolute paths, and the root itself.
if (path.dirname(uploadDir) !== datasetsPath || uploadDir === datasetsPath) {
return NextResponse.json({ error: 'Invalid dataset name' }, { status: 400 });
}
// Create upload directory if it doesn't exist
const uploadDir = join(datasetsPath, datasetName);
await mkdir(uploadDir, { recursive: true });
const savedFiles: string[] = [];
// Process files sequentially to avoid overwhelming the system
for (let i = 0; i < files.length; i++) {
const file = files[i] as any;
+1 -1
View File
@@ -1 +1 @@
VERSION = "0.13.11"
VERSION = "0.13.12"