You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ZIP upload (Drop) falsely flags SvelteKit files starting with "+" as path traversal #5185
Create a SvelteKit project containing a file named +page.svelte or +layout.svelte in src/routes (this is a standard SvelteKit naming convention).
Zip the project so that Dockerfile, package.json, and src/ are at the root of the zip.
Create a new Application service in Dokploy.
Choose "Drop" as the source and upload the zip file.
Set Build Type to "Dockerfile" and click Deploy.
Current vs. Expected behavior
Following the steps above, I expected the ZIP to be extracted normally, since +page.svelte is a valid filename and not an attempt at path traversal.
Instead, the deployment fails immediately with "Error saving the deployment" in the UI. The Dokploy container logs (docker logs <dokploy-container>) show:
Error processing ZIP file: Error: Path traversal detected: resolved path escapes output directory: src/routes/+layout.svelte
at o (.next/server/chunks/8772.js:275:5179)
at async (.next/server/chunks/6355.js:124:17297)
This repeats for every file in the zip whose name starts with "+". It looks like the path-traversal guard misinterprets a leading "+" character as part of a relative-path token, causing a false positive — "+" is a valid filename character with no path semantics.
Workaround: renaming files from +page.svelte to e.g. __PLUS__page.svelte before zipping, then restoring the real name inside the Dockerfile before the build step (RUN mv __PLUS__page.svelte +page.svelte, etc.). This works but shouldn't be necessary.
Provide environment information
Operating System:
OS: Ubuntu 24.04
Arch: amd64
Dokploy version: 0.30.2
VPS Provider: webh
What applications/services are you trying to deploy? SvelteKit app (adapter-node) built via Dockerfile
Which area(s) are affected? (Select all that apply)
Application
Are you deploying the applications where Dokploy is installed or on a remote server?
Same server where Dokploy is installed
Additional context
This only affects the "Drop" ZIP upload path. We have not tested whether a Git-based source is affected — the workaround suggests it likely isn't, since the bug is specifically in the ZIP extraction/validation step.
I found the root cause. The readValidDirectory function validates ZIP entry paths against this regex allowlist:
/^[\w/. :[\]-]{1,500}$/
The + character is not in that character class (\w, /, ., , :, [, ], -), so any path containing + (like src/routes/+page.svelte) immediately fails the check and the function returns false. The ZIP extraction code in drop.ts then treats that false return as a path traversal attempt and throws the error you're seeing.
The fix is to add + to the allowed character class in packages/server/src/wss/utils.ts:
The + character has no path traversal semantics — it's a regular filename character. The actual traversal protection is correctly handled on lines 49–54 via path.resolve() comparison against the base path. The regex is only a pre-filter for obviously malformed paths, and it's currently too restrictive.
Activity
linear-code commentedon Aug 25, 2026
DOK-694
dosubot commentedon Aug 25, 2026
Hi @bAleksiejczuk! I'm Dosu and I'm helping the Dokploy team.
I found the root cause. The
readValidDirectoryfunction validates ZIP entry paths against this regex allowlist:The
+character is not in that character class (\w,/,.,,:,[,],-), so any path containing+(likesrc/routes/+page.svelte) immediately fails the check and the function returnsfalse. The ZIP extraction code indrop.tsthen treats thatfalsereturn as a path traversal attempt and throws the error you're seeing.The fix is to add
+to the allowed character class inpackages/server/src/wss/utils.ts:The
+character has no path traversal semantics — it's a regular filename character. The actual traversal protection is correctly handled on lines 49–54 viapath.resolve()comparison against the base path. The regex is only a pre-filter for obviously malformed paths, and it's currently too restrictive.To reply, just mention @dosu.
Docs are dead. Just use Dosu.