Lookup for vulnerable packages by Package URL.

Purlpkg:npm/%40saltcorn/server@1.1.0-beta.22
Typenpm
Namespace@saltcorn
Nameserver
Version1.1.0-beta.22
Qualifiers
Subpath
Is_vulnerabletrue
Next_non_vulnerable_version1.4.6
Latest_non_vulnerable_version1.6.0-beta.5
Affected_by_vulnerabilities
0
url VCID-d5ew-szns-kucd
vulnerability_id VCID-d5ew-szns-kucd
summary
Saltcorn has an Unauthenticated Path Traversal in sync endpoints, allowing arbitrary file write and directory read
### Summary

Two unauthenticated path traversal vulnerabilities exist in Saltcorn's mobile sync endpoints. The `POST /sync/offline_changes` endpoint allows an unauthenticated attacker to create arbitrary directories and write a `changes.json` file with attacker-controlled JSON content anywhere on the server filesystem. The `GET /sync/upload_finished` endpoint allows an unauthenticated attacker to list arbitrary directory contents and read specific JSON files.

The safe path validation function `File.normalise_in_base()` exists in the codebase and is correctly used by the `clean_sync_dir` endpoint in the **same file** (fix for GHSA-43f3-h63w-p6f6), but was not applied to these two endpoints.

### Details

**Finding 1: Arbitrary file write — `POST /sync/offline_changes` (sync.js line 226)**

The `newSyncTimestamp` parameter from the request body is used directly in `path.join()` without sanitization:

```javascript
const syncDirName = `${newSyncTimestamp}_${req.user?.email || "public"}`;
const syncDir = path.join(
    rootFolder.location, "mobile_app", "sync", syncDirName
);
await fs.mkdir(syncDir, { recursive: true });        // creates arbitrary dir
await fs.writeFile(
    path.join(syncDir, "changes.json"),
    JSON.stringify(changes)                           // writes attacker content
);
```

No authentication middleware is applied to this route. Since `path.join()` normalizes `../` sequences, setting `newSyncTimestamp` to `../../../../tmp/evil` causes the path to resolve outside the sync directory.

**Finding 2: Arbitrary directory read — `GET /sync/upload_finished` (sync.js line 288)**

The `dir_name` query parameter is used directly in `path.join()` without sanitization:

```javascript
const syncDir = path.join(
    rootFolder.location, "mobile_app", "sync", dir_name
);
let entries = await fs.readdir(syncDir);
```

Also unauthenticated. An attacker can list directory contents and read files named `translated-ids.json`, `unique-conflicts.json`, `data-conflicts.json`, or `error.json` from any directory.

**Contrast — fixed endpoint in the same file (line 342):**

The `clean_sync_dir` endpoint correctly uses `File.normalise_in_base()`:

```javascript
const syncDir = File.normalise_in_base(
    path.join(rootFolder.location, "mobile_app", "sync"),
    dir_name
);
if (syncDir) await fs.rm(syncDir, { recursive: true, force: true });
```

### PoC

```bash
# Write arbitrary file to /tmp/
curl -X POST http://TARGET:3000/sync/offline_changes \
  -H "Content-Type: application/json" \
  -d '{
    "newSyncTimestamp": "../../../../tmp/saltcorn_poc",
    "oldSyncTimestamp": "0",
    "changes": {"proof": "path_traversal_write"}
  }'
# Result: /tmp/saltcorn_poc_public/changes.json created with attacker content

# List /etc/ directory
curl "http://TARGET:3000/sync/upload_finished?dir_name=../../../../etc"
```

### Impact

- **Unauthenticated arbitrary directory creation** anywhere on the filesystem
- **Unauthenticated arbitrary JSON file write** (`changes.json`) to any writable directory
- **Unauthenticated directory listing** of arbitrary directories
- **Unauthenticated read** of specific JSON files from arbitrary directories
- Potential for **remote code execution** via writing to sensitive paths (cron, systemd, Node.js module paths)

### Remediation

Apply `File.normalise_in_base()` to both endpoints, matching the existing pattern in `clean_sync_dir`:

```javascript
// offline_changes fix
const syncDirName = `${newSyncTimestamp}_${req.user?.email || "public"}`;
const syncDir = File.normalise_in_base(
    path.join(rootFolder.location, "mobile_app", "sync"),
    syncDirName
);
if (!syncDir) {
    return res.status(400).json({ error: "Invalid sync directory name" });
}

// upload_finished fix
const syncDir = File.normalise_in_base(
    path.join(rootFolder.location, "mobile_app", "sync"),
    dir_name
);
if (!syncDir) {
    return res.json({ finished: false });
}
```

Additionally, add `loggedIn` middleware to endpoints that modify server state.
references
0
reference_url https://api.first.org/data/v1/epss?cve=CVE-2026-40163
reference_id
reference_type
scores
0
value 0.00239
scoring_system epss
scoring_elements 0.47194
published_at 2026-06-09T12:55:00Z
1
value 0.00239
scoring_system epss
scoring_elements 0.47227
published_at 2026-06-05T12:55:00Z
2
value 0.00239
scoring_system epss
scoring_elements 0.4723
published_at 2026-06-06T12:55:00Z
3
value 0.00239
scoring_system epss
scoring_elements 0.47211
published_at 2026-06-07T12:55:00Z
4
value 0.00239
scoring_system epss
scoring_elements 0.47181
published_at 2026-06-08T12:55:00Z
url https://api.first.org/data/v1/epss?cve=CVE-2026-40163
1
reference_url https://github.com/saltcorn/saltcorn
reference_id
reference_type
scores
0
value 8.2
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
1
value HIGH
scoring_system generic_textual
scoring_elements
url https://github.com/saltcorn/saltcorn
2
reference_url https://github.com/saltcorn/saltcorn/security/advisories/GHSA-32pv-mpqg-h292
reference_id
reference_type
scores
0
value 8.2
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
1
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
2
value HIGH
scoring_system generic_textual
scoring_elements
3
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:Y/T:P/P:M/B:A/M:M/D:T/2026-04-15T14:49:25Z/
url https://github.com/saltcorn/saltcorn/security/advisories/GHSA-32pv-mpqg-h292
3
reference_url https://nvd.nist.gov/vuln/detail/CVE-2026-40163
reference_id
reference_type
scores
0
value 8.2
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
1
value HIGH
scoring_system generic_textual
scoring_elements
url https://nvd.nist.gov/vuln/detail/CVE-2026-40163
4
reference_url https://github.com/advisories/GHSA-32pv-mpqg-h292
reference_id GHSA-32pv-mpqg-h292
reference_type
scores
0
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-32pv-mpqg-h292
fixed_packages
0
url pkg:npm/%40saltcorn/server@1.4.5
purl pkg:npm/%40saltcorn/server@1.4.5
is_vulnerable true
affected_by_vulnerabilities
0
vulnerability VCID-n1q4-umca-e7g7
1
vulnerability VCID-va1x-6pqx-qqfk
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540saltcorn/server@1.4.5
1
url pkg:npm/%40saltcorn/server@1.5.5
purl pkg:npm/%40saltcorn/server@1.5.5
is_vulnerable true
affected_by_vulnerabilities
0
vulnerability VCID-n1q4-umca-e7g7
1
vulnerability VCID-va1x-6pqx-qqfk
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540saltcorn/server@1.5.5
2
url pkg:npm/%40saltcorn/server@1.6.0-beta.4
purl pkg:npm/%40saltcorn/server@1.6.0-beta.4
is_vulnerable true
affected_by_vulnerabilities
0
vulnerability VCID-n1q4-umca-e7g7
1
vulnerability VCID-va1x-6pqx-qqfk
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540saltcorn/server@1.6.0-beta.4
aliases CVE-2026-40163, GHSA-32pv-mpqg-h292
risk_score 4.0
exploitability 0.5
weighted_severity 8.0
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-d5ew-szns-kucd
1
url VCID-n1q4-umca-e7g7
vulnerability_id VCID-n1q4-umca-e7g7
summary
Saltcorn: SQL Injection via Unparameterized Sync Endpoints (maxLoadedId)
### Summary
A critical SQL injection vulnerability in Saltcorn’s mobile-sync routes allows any authenticated low-privilege user with read access to at least one table to inject arbitrary SQL through sync parameters. This can lead to full database exfiltration, including admin password hashes and configuration secrets, and may also enable database modification or destruction depending on the backend. 

### Details
The issue affects the mobile-sync endpoints:

- `POST /sync/load_changes`
- `POST /sync/deletes`

According to the provided analysis, user-controlled values from the request body are interpolated directly into SQL template literals without parameterization, type enforcement, or sanitization. In particular, `req.body.syncInfos[tableName].maxLoadedId` is embedded into SQL in `getSyncRows()` and timestamp-derived values are similarly interpolated in `getDelRows()`. 

Relevant vulnerable code paths include:

- `packages/server/routes/sync.js` — `getSyncRows()`
  - branch using `where data_tbl."${db.sqlsanitize(pkName)}" > ${syncInfo.maxLoadedId}`
  - branch using `and info_tbl.ref > ${syncInfo.maxLoadedId}`
- `packages/server/routes/sync.js` — `getDelRows()`
  - timestamp expressions built from request-controlled values and inserted into SQL
- `packages/server/routes/sync.js` — `/load_changes` route handler
  - request body fields are passed into the SQL-building functions without validation or safe binding

The root cause is that values are treated as trusted SQL fragments rather than bound parameters. While `db.sqlsanitize()` is used for identifiers elsewhere, that does not protect interpolated values and is not intended to prevent value-based SQL injection. The report notes there is no `parseInt()`, numeric validation, or prepared-statement binding before these values are concatenated into the query string. 

This means a normal authenticated user can escape the intended query logic and execute arbitrary SQL in the context of the application database. The provided evidence demonstrates successful extraction of user records and schema information through the vulnerable sync route, confirming that the injection is practically exploitable. 

### PoC
Based on the provided report, the issue can be reproduced by authenticating as a normal user, sending a crafted request to the affected sync endpoint, and placing a malicious SQL expression into the sync metadata field that is later interpolated into the backend query. Successful exploitation returns attacker-selected database contents in the sync response. 

### Impact
- **Type:** SQL injection
- **Who is impacted:** Any Saltcorn deployment exposing the affected mobile-sync routes to authenticated users
- **Security impact:** An authenticated low-privilege user may exfiltrate the full database, including password hashes, configuration secrets, application data, and schema information; on some backends, the same flaw may also permit writes, schema changes, or destructive operations
- **Attack preconditions:** The attacker needs a valid authenticated account with access to at least one readable table through the sync feature
- **Privilege impact:** The issue allows escalation from normal user access to database-wide compromise
references
0
reference_url https://api.first.org/data/v1/epss?cve=CVE-2026-41478
reference_id
reference_type
scores
0
value 0.00037
scoring_system epss
scoring_elements 0.11436
published_at 2026-06-06T12:55:00Z
1
value 0.00037
scoring_system epss
scoring_elements 0.11335
published_at 2026-06-09T12:55:00Z
2
value 0.00037
scoring_system epss
scoring_elements 0.11319
published_at 2026-06-08T12:55:00Z
3
value 0.00037
scoring_system epss
scoring_elements 0.11399
published_at 2026-06-07T12:55:00Z
4
value 0.00037
scoring_system epss
scoring_elements 0.11439
published_at 2026-06-05T12:55:00Z
url https://api.first.org/data/v1/epss?cve=CVE-2026-41478
1
reference_url https://github.com/saltcorn/saltcorn
reference_id
reference_type
scores
0
value 9.9
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
1
value CRITICAL
scoring_system generic_textual
scoring_elements
url https://github.com/saltcorn/saltcorn
2
reference_url https://github.com/saltcorn/saltcorn/security/advisories/GHSA-jp74-mfrx-3qvh
reference_id
reference_type
scores
0
value 10
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
1
value 9.9
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
2
value CRITICAL
scoring_system cvssv3.1_qr
scoring_elements
3
value CRITICAL
scoring_system generic_textual
scoring_elements
4
value Track*
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:N/T:T/P:M/B:A/M:M/D:R/2026-04-27T13:10:53Z/
url https://github.com/saltcorn/saltcorn/security/advisories/GHSA-jp74-mfrx-3qvh
3
reference_url https://nvd.nist.gov/vuln/detail/CVE-2026-41478
reference_id
reference_type
scores
0
value 9.9
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
1
value CRITICAL
scoring_system generic_textual
scoring_elements
url https://nvd.nist.gov/vuln/detail/CVE-2026-41478
4
reference_url https://github.com/advisories/GHSA-jp74-mfrx-3qvh
reference_id GHSA-jp74-mfrx-3qvh
reference_type
scores
0
value CRITICAL
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-jp74-mfrx-3qvh
fixed_packages
0
url pkg:npm/%40saltcorn/server@1.4.6
purl pkg:npm/%40saltcorn/server@1.4.6
is_vulnerable false
affected_by_vulnerabilities
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540saltcorn/server@1.4.6
1
url pkg:npm/%40saltcorn/server@1.5.6
purl pkg:npm/%40saltcorn/server@1.5.6
is_vulnerable false
affected_by_vulnerabilities
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540saltcorn/server@1.5.6
2
url pkg:npm/%40saltcorn/server@1.6.0-beta.5
purl pkg:npm/%40saltcorn/server@1.6.0-beta.5
is_vulnerable false
affected_by_vulnerabilities
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540saltcorn/server@1.6.0-beta.5
aliases CVE-2026-41478, GHSA-jp74-mfrx-3qvh
risk_score 4.5
exploitability 0.5
weighted_severity 9.0
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-n1q4-umca-e7g7
2
url VCID-va1x-6pqx-qqfk
vulnerability_id VCID-va1x-6pqx-qqfk
summary
Saltcorn: Open Redirect in `POST /auth/login` due to incomplete `is_relative_url` validation (backslash bypass)
### Summary
Saltcorn validates the post-login `dest` parameter with a string check that only blocks `:/` and `//`. Because all WHATWG-compliant browsers normalise backslashes (`\`) to forward slashes (`/`) for special schemes, a payload such as `/\evil.com/path` slips through `is_relative_url()`, is emitted unchanged in the HTTP `Location` header, and causes the browser to navigate cross-origin to an attacker-controlled domain. The bug is reachable on a default install and only requires a victim who can be tricked into logging in via a crafted Saltcorn URL.

### Details
Vulnerable function: `packages/server/routes/utils.js:393-395`

```js
const is_relative_url = (url) => {
  return typeof url === "string" && !url.includes(":/") && !url.includes("//");
};
```

The function's intent is to allow only same-origin redirects, but the allow-list only checks for two literal substrings. It does not handle:
- backslash characters, which WHATWG URL parsing (used by every modern browser) treats as forward slashes for the special schemes `http`, `https`, `ftp`, `ws`, `wss`. A URL parser fed `/\evil.com/path` with a base of `http://victim/` resolves to `http://evil.com/path`.
- non-`http(s):` schemes that do not contain `:/`. The strings `javascript:alert(1)`, `data:text/html,...`, `vbscript:...` all pass.

Vulnerable callsite: `packages/server/auth/routes.js:1371-1376`

```js
} else if (
  (req.body || {}).dest &&
  is_relative_url(decodeURIComponent((req.body || {}).dest))
) {
  res.redirect(decodeURIComponent((req.body || {}).dest));
} else res.redirect("/");
```

The body's `dest` is URL-decoded twice (once by body-parser, once by the explicit `decodeURIComponent`) and the same value is passed to `res.redirect`. Express 5's `res.redirect` runs the value through `encodeurl@2.0.0`, whose whitelist character class `[^\x21\x23-\x3B\x3D\x3F-\x5F\x61-\x7A\x7C\x7E]` includes `\x5C` (backslash). The backslash is therefore not percent-encoded and ends up verbatim in the `Location` response header.

### PoC
[poc.zip](https://github.com/user-attachments/files/26678853/poc.zip)

Please extract the uploaded compressed file before proceeding
1. ./setup.sh
2. ./poc.sh

<img width="419" height="71" alt="스크린샷 2026-04-13 오후 11 44 36" src="https://github.com/user-attachments/assets/9c919ed4-167b-47e3-9873-733f97b44bf0" />

### Impact
Any user who can be lured into clicking a Saltcorn login URL crafted by the attacker will, after submitting their valid credentials, be redirected to an attacker-controlled origin. The redirect happens under the trusted Saltcorn domain, so the user has no visual cue that they are about to leave the site. Realistic abuse patterns:

- Credential phishing — the attacker's site renders a forged "session expired, please log in again" prompt to capture the password the user just typed.
references
0
reference_url https://api.first.org/data/v1/epss?cve=CVE-2026-42259
reference_id
reference_type
scores
0
value 0.00017
scoring_system epss
scoring_elements 0.04642
published_at 2026-06-05T12:55:00Z
1
value 0.00017
scoring_system epss
scoring_elements 0.04616
published_at 2026-06-07T12:55:00Z
2
value 0.00017
scoring_system epss
scoring_elements 0.04628
published_at 2026-06-06T12:55:00Z
3
value 0.00019
scoring_system epss
scoring_elements 0.05351
published_at 2026-06-09T12:55:00Z
4
value 0.00019
scoring_system epss
scoring_elements 0.05307
published_at 2026-06-08T12:55:00Z
url https://api.first.org/data/v1/epss?cve=CVE-2026-42259
1
reference_url https://github.com/saltcorn/saltcorn
reference_id
reference_type
scores
0
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
1
value MODERATE
scoring_system generic_textual
scoring_elements
url https://github.com/saltcorn/saltcorn
2
reference_url https://github.com/saltcorn/saltcorn/security/advisories/GHSA-f3g8-9xv5-77gv
reference_id
reference_type
scores
0
value MODERATE
scoring_system cvssv3.1_qr
scoring_elements
1
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
2
value MODERATE
scoring_system generic_textual
scoring_elements
3
value Track
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:N/T:P/P:M/B:A/M:M/D:T/2026-05-08T22:55:52Z/
url https://github.com/saltcorn/saltcorn/security/advisories/GHSA-f3g8-9xv5-77gv
3
reference_url https://nvd.nist.gov/vuln/detail/CVE-2026-42259
reference_id
reference_type
scores
0
value 5.1
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
1
value MODERATE
scoring_system generic_textual
scoring_elements
url https://nvd.nist.gov/vuln/detail/CVE-2026-42259
4
reference_url https://github.com/advisories/GHSA-f3g8-9xv5-77gv
reference_id GHSA-f3g8-9xv5-77gv
reference_type
scores
0
value MODERATE
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-f3g8-9xv5-77gv
fixed_packages
0
url pkg:npm/%40saltcorn/server@1.4.6
purl pkg:npm/%40saltcorn/server@1.4.6
is_vulnerable false
affected_by_vulnerabilities
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540saltcorn/server@1.4.6
1
url pkg:npm/%40saltcorn/server@1.5.6
purl pkg:npm/%40saltcorn/server@1.5.6
is_vulnerable false
affected_by_vulnerabilities
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540saltcorn/server@1.5.6
2
url pkg:npm/%40saltcorn/server@1.6.0-beta.5
purl pkg:npm/%40saltcorn/server@1.6.0-beta.5
is_vulnerable false
affected_by_vulnerabilities
resource_url http://public2.vulnerablecode.io/packages/pkg:npm/%2540saltcorn/server@1.6.0-beta.5
aliases CVE-2026-42259, GHSA-f3g8-9xv5-77gv
risk_score 3.1
exploitability 0.5
weighted_severity 6.2
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-va1x-6pqx-qqfk
Fixing_vulnerabilities
Risk_score4.5
Resource_urlhttp://public2.vulnerablecode.io/packages/pkg:npm/%2540saltcorn/server@1.1.0-beta.22