Gửi #1015958: DataLinkDC dinky v1.2.5 (commit ce7678e) Path Traversalthông tin

tiêu đềDataLinkDC dinky v1.2.5 (commit ce7678e) Path Traversal
Mô tảRequired fields (Submission Policy: vendor, product, affected versions, vulnerability class) - **Vendor**: DataLinkDC - **Product**: dinky (dinky-admin) - **Affected version(s)**: up to and including released tag v1.2.5 (reviewed at commit ce7678eaa13722541f7d1eeda7ffbf8c9f753e20; v1.2.5 was the newest release at the time of review) - **Vulnerability class**: Path traversal — arbitrary file overwrite / deletion (CWE-22) Preconditions - **Authentication / preconditions**: any authenticated dinky user can trigger this. The controller carries a class-level `@SaCheckLogin` only (`CatalogueController.java:73`); the upload route adds no `@SaCheckPermission`, so no role beyond a valid session is required — the filesystem chain involves no tenant or permission escalation. - **CVSS**: assigned by VulDB during moderation; not claimed by the submitter. Optional vector hint only (not a claim), to speed the review: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H Title (one line) Multipart filename path traversal in the Dinky catalogue zip upload overwrites and deletes files outside the dinky root directory Description (technical, moderator-ready) Multipart filename path traversal in the Dinky catalogue zip upload overwrites and deletes files outside the dinky root directory Data flow: multipart `filename` → `file.getOriginalFilename()` → `zipPath = filePath + File.separator + fileName` → `FileUtil.writeBytes(file.getBytes(), zipPath)` → `finally { FileUtil.del(zipFile); }` Affected interfaces | Interface | |---| | POST /api/catalogue/upload/{id} — multipart form field `file`; the client-controlled Content-Disposition `filename` is the injection vector (`../` escapes the dinky root directory) | Primary route detail: ``` POST /api/catalogue/upload/{id} Content-Type: multipart/form-data file=@<zip>;filename=../<name> <- the client-controlled Content-Disposition filename ``` Any authenticated dinky user can overwrite and then delete arbitrary files writable by the dinky OS account — including application jars and configs under the install directory and `../`-reached files outside it — because the route concatenates the client-controlled multipart filename onto the dinky root directory with no normalization or boundary check, writes the uploaded zip bytes to that path, and deletes the same attacker-named path in a `finally` block. A pre-existing file at the escaped path is destroyed by the overwrite-then-delete chain. Root cause 1. `String fileName = file.getOriginalFilename();` (`CatalogueController.java:89`) — Spring/Tomcat pass the client's Content-Disposition filename through unsanitized; `..` separators are preserved. 2. `String zipPath = filePath + File.separator + fileName;` (`CatalogueController.java:90`) — plain string concatenation with the dinky root dir (shipped default `DirConstant.getRootPath()` = `user.dir`); no normalization and no boundary check, so `../` escapes the root. 3. `FileUtil.writeBytes(file.getBytes(), zipPath)` (`CatalogueController.java:99`) writes the attacker's bytes to the escaped path; `FileUtil.del(zipFile)` on the same `new File(zipPath)` runs in the `finally` block (`CatalogueController.java:105`), so the operation ends with the attacker-named path deleted — together an overwrite-then-delete of any file writable by the dinky OS user, and a deletion of any pre-existing file at the path. 4. The archive-entry writes inside the subsequent unzip are protected by hutool 5.8.31 `checkSlip` (`ZipReader.java:171-172`); this issue is the *filename* path, which bypasses hutool entirely through raw `java.io.File` construction. Missing guard: nothing validates that the final canonical path stays inside the dinky root directory before the write and the delete. Proof of concept Baseline: dinky v1.2.5 official distribution, self-hosted instance on the reporter's own host at 127.0.0.1:18888 (H2 default profile), authenticated with a seeded administrator session. Victim file `work/cv4probe7740` (7 bytes, content `victim`) placed **outside** the dinky root dir (`work/dk-dist`); payload `/tmp/plain7737.zip`, a minimal harmless zip with entry `a.txt`. **1. Upload with a traversing filename** ```sh $ curl -s -X POST -H "dinky-token: <admin session>" \ -F "file=@/tmp/plain7737.zip;filename=../cv4probe7740" \ "http://127.0.0.1:18888/api/catalogue/upload/1" ``` **2. Positive artifact — the victim file outside the root is overwritten and deleted** - Before: `work/cv4probe7740` exists, 7 bytes. - After: `ls: cannot access work/cv4probe7740: No such file or directory` — the file was overwritten with the attacker's zip bytes (`FileUtil.writeBytes` inside `try`) and then deleted by the `finally { FileUtil.del(zipFile); }` block. - Independent proof the raw filename (separators and `..`) reached the filesystem: the zip's entry `a.txt` was extracted into the root dir — `work/dk-dist/a.txt` existed after the request. **3. Negative control** The hutool 5.8.31 `checkSlip` guard inside `ZipUtil.unzip` blocked archive-entry escape attempts (entry paths did not escape the root), and a request with `filename=../probe7738.zip` left no file anywhere after completion (the write-then-delete window closes in `finally`) — the exposed primitive is exactly the filename write plus the resulting delete, not a zip-slip. Impact See the interface and root-cause sections: an actor who satisfies the stated preconditions makes the application write attacker-controlled bytes to, and then delete, a file path of the attacker's choosing outside the intended root directory, crossing the trust boundary described above. A logged-in user can destroy (delete) arbitrary files, or briefly overwrite them with attacker content, anywhere the dinky OS account can write — application jars/configs under the install dir, `../`-reaching user files — causing loss of integrity and availability of the deployment. References - Project repository: https://github.com/DataLinkDC/dinky - Security policy: `SECURITY.md` in that repository. Coordinated disclosure: vendor notified 2026-10-06 via GitHub Private Vulnerability Reporting (https://github.com/DataLinkDC/dinky/security/advisories/GHSA-2jp7-3h24-h6r7); not publicly disclosed; no CVE assigned. Duplicate check: public advisories and the issue tracker were searched before reporting.
Nguồn⚠️ https://github.com/DataLinkDC/dinky/security/advisories/GHSA-2jp7-3h24-h6r7
Người dùng
 lucasg2g (UID 84737)
Đệ trình06/10/2026 14:45 (cách đây 1 tháng)
Kiểm duyệt07/11/2026 20:25 (1 month later)
Trạng tháiđược chấp nhận
Mục VulDB432647 [DataLinkDC Dinky đến 1.2.5 Catalogue Upload CatalogueController.java file.getOriginalFilename filename duyệt thư mục]
điểm20

Are you interested in using VulDB?

Download the whitepaper to learn more about our service!