Skip to content

Commit b7eff15

Browse files
committed
satisfy codeQL
1 parent 884496c commit b7eff15

5 files changed

Lines changed: 29 additions & 187 deletions

File tree

.gitignore

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@ backend/prisma/dev.db
1111
backend/prisma/e2e-test.db
1212
backend/prisma/*.backup
1313

14+
# SQLite artifacts anywhere (avoid committing dev DBs)
15+
*.db
16+
*.db-journal
17+
*.db-wal
18+
*.db-shm
19+
*.db.backup
20+
21+
# Docker-entrypoint persisted secrets/locks (in case prisma volume is bind-mounted)
22+
backend/prisma/.jwt_secret
23+
backend/prisma/.csrf_secret
24+
backend/prisma/.migration-lock/
25+
26+
# Local OIDC/Keycloak dev files
27+
docker-compose.oidc.local.yml
28+
ops/keycloak/realm-excalidash-local.json
29+
1430
# Uploads
1531
backend/uploads/
1632

@@ -109,4 +125,4 @@ Thumbs.db
109125

110126
# Temporary files
111127
*.tmp
112-
*.temp
128+
*.temp

backend/dev_v3.db

Whitespace-only changes.

backend/src/routes/importExport/excalidashImportRoutes.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,8 @@ import {
1515

1616
const isSafeMulterTempFilename = (value: string): boolean => /^[a-f0-9]{32}$/.test(value);
1717

18-
const isPathInsideDirectory = (candidatePath: string, rootDir: string): boolean => {
19-
const relativePath = path.relative(rootDir, candidatePath);
20-
return relativePath === "" || (!relativePath.startsWith("..") && !path.isAbsolute(relativePath));
21-
};
22-
2318
const resolveStagedUploadPath = async (
24-
file: { filename?: unknown },
19+
file: { filename?: unknown; path?: unknown },
2520
uploadRoot: string
2621
): Promise<string> => {
2722
const absoluteUploadRoot = path.resolve(uploadRoot);
@@ -33,13 +28,20 @@ const resolveStagedUploadPath = async (
3328
throw new ImportValidationError("Invalid upload path");
3429
}
3530

36-
const filename = typeof file.filename === "string" ? file.filename : "";
37-
if (!isSafeMulterTempFilename(filename)) {
31+
// CodeQL path-injection: use basename extraction + strict allowlist, then enforce root containment.
32+
// Multer typically generates a server-side random filename; we still validate defensively.
33+
const rawPath = typeof file.path === "string" ? file.path : "";
34+
const rawFilename = typeof file.filename === "string" ? file.filename : "";
35+
const basename = path.basename(rawPath || rawFilename);
36+
if (!isSafeMulterTempFilename(basename)) {
3837
throw new ImportValidationError("Invalid upload path");
3938
}
4039

41-
const candidatePath = path.resolve(canonicalUploadRoot, filename);
42-
if (!isPathInsideDirectory(candidatePath, canonicalUploadRoot)) {
40+
const candidatePath = path.resolve(canonicalUploadRoot, basename);
41+
const rootPrefix = canonicalUploadRoot.endsWith(path.sep)
42+
? canonicalUploadRoot
43+
: `${canonicalUploadRoot}${path.sep}`;
44+
if (!candidatePath.startsWith(rootPrefix)) {
4345
throw new ImportValidationError("Invalid upload path");
4446
}
4547

docker-compose.oidc.local.yml

Lines changed: 0 additions & 112 deletions
This file was deleted.

ops/keycloak/realm-excalidash-local.json

Lines changed: 0 additions & 64 deletions
This file was deleted.

0 commit comments

Comments
 (0)