From 08ec3c9a7047adeffe95765010ae5e86d4c5c50d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:07:23 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[CRITICAL]?= =?UTF-8?q?=20Fix=20Path=20Traversal=20in=20AbstractDiskBasedService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: tomdesair <14034630+tomdesair@users.noreply.github.com> --- .jules/sentinel.md | 4 ++++ .../tus/server/upload/disk/AbstractDiskBasedService.java | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..e3a68fb --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2026-06-16 - [Fix path traversal vulnerability in disk storage service] +**Vulnerability:** Path traversal vulnerability in `AbstractDiskBasedService`. The method `getPathInStorageDirectory(UploadId id)` resolved the path dynamically from `id.toString()` without bounds checking, which could allow an attacker to read/write arbitrary files given an ID payload containing directory traversal sequences `..` or URL encoded path variants (`%2E%2E`). +**Learning:** `URLCodec.encode` might not correctly sanitize path traversal characters. An attacker can set an ID value like `..`, which would bypass the encode step because `.decode("..")` evaluates to `..`. Therefore, input sanitization should verify the absolute directory boundaries. +**Prevention:** Use Java `java.nio.file.Path` to resolve the full absolute path and ensure the path is within bounds using `startsWith()` logic on normalized absolute paths. diff --git a/src/main/java/me/desair/tus/server/upload/disk/AbstractDiskBasedService.java b/src/main/java/me/desair/tus/server/upload/disk/AbstractDiskBasedService.java index 0c12472..58ce045 100644 --- a/src/main/java/me/desair/tus/server/upload/disk/AbstractDiskBasedService.java +++ b/src/main/java/me/desair/tus/server/upload/disk/AbstractDiskBasedService.java @@ -37,7 +37,12 @@ protected Path getPathInStorageDirectory(UploadId id) { if (id == null) { return null; } else { - return storagePath.resolve(id.toString()); + Path resolvedPath = storagePath.resolve(id.toString()); + Path normalizedStoragePath = storagePath.toAbsolutePath().normalize(); + if (!resolvedPath.toAbsolutePath().normalize().startsWith(normalizedStoragePath)) { + throw new IllegalArgumentException("Upload ID violates storage path boundaries"); + } + return resolvedPath; } }