---
title: "Check the sender and content of every · Agent Wranglers"
url: https://agentwranglers.se/playbook/desktop-apps/web-code-inside-desktop-apps/validate-ipc
id: DSK-11
level: Recommended
updated: 2026-10-22
tokens: 1059
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Check the sender and content of every message to the main process

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Web code inside desktop apps](https://agentwranglers.se/playbook/desktop-apps/web-code-inside-desktop-apps.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-22.

- ID: DSK-11
- Level: Recommended
- Chapter: [Web code inside desktop apps](https://agentwranglers.se/playbook/desktop-apps/web-code-inside-desktop-apps.md)
- Rule: Each handler in the main process checks which window and page sent the message and validates every argument against a schema. A path or command never comes from the page as is.
- Check: A test calls each handler with a sender frame from another address. It refuses. A test sends `../../.ssh/id_rsa` as an invoice ID. The handler refuses it and opens no file.
- How: Treat the window as you treat a browser talking to a server. The main process holds the power, and the window can be fooled by injected script. Check `event.senderFrame.url` against your own app address. Validate types and lengths as [accept only the fields you expect](https://agentwranglers.se/playbook/adversarial-testing/access-and-accounts/mass-assignment.md) does. Take an ID and look up the path yourself. When a handler starts a program, follow [never pass input to a shell](https://agentwranglers.se/playbook/adversarial-testing/injection/command-injection.md).

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
const APP_ORIGIN = 'app://ledgerly';
const InvoiceId = z.string().regex(/^inv_[a-z0-9]{12}$/);

ipcMain.handle('invoice:open', (event, rawId) => {
  if (new URL(event.senderFrame.url).origin !== APP_ORIGIN) throw new Error('unknown sender');
  const id = InvoiceId.parse(rawId);
  return invoices.open(path.join(invoiceDir, `${id}.pdf`));
});
```

### Plain text example

```rust
#[tauri::command]
fn open_invoice(id: String, dir: tauri::State<InvoiceDir>) -> Result<Vec<u8>, String> {
    let valid = id.len() == 16 && id.starts_with("inv_") && id[4..].chars().all(|c| c.is_ascii_alphanumeric());
    if !valid {
        return Err("bad invoice id".into());
    }
    std::fs::read(dir.0.join(format!("{id}.pdf"))).map_err(|_| "not found".into())
}
```

## Sources

- [Electron security checklist (validate the sender of IPC messages)](https://www.electronjs.org/docs/latest/tutorial/security)

## Related rules

- SEC-25 [Accept only the fields you expect](https://agentwranglers.se/playbook/adversarial-testing/access-and-accounts/mass-assignment.md) in Adversarial testing
- SEC-11 [Never pass input to a shell](https://agentwranglers.se/playbook/adversarial-testing/injection/command-injection.md) in Adversarial testing
- DSK-12 [Open outside links only after checking the address](https://agentwranglers.se/playbook/desktop-apps/web-code-inside-desktop-apps/safe-external-links.md) in Desktop apps, extensions and CLIs
- DSK-16 [Treat messages from web pages and content scripts as untrusted](https://agentwranglers.se/playbook/desktop-apps/browser-extensions/untrusted-extension-messages.md) in Desktop apps, extensions and CLIs

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/desktop-apps/web-code-inside-desktop-apps/validate-ipc">Agent Wranglers desktop apps, extensions and CLIs playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Keep web content away from the operating system](https://agentwranglers.se/playbook/desktop-apps/web-code-inside-desktop-apps/isolate-web-content.md)
- Next: [Open outside links only after checking the address](https://agentwranglers.se/playbook/desktop-apps/web-code-inside-desktop-apps/safe-external-links.md)
- [Web code inside desktop apps](https://agentwranglers.se/playbook/desktop-apps/web-code-inside-desktop-apps.md)
