# On Windows, Cursor’s hook stdin JSON payload includes a UTF-8 BOM that breaks standard JSON.parse(), causing security guards to silently degrade to allowing commands across all agent channels

**URL:** <https://forum.cursor.com/t/on-windows-cursor-s-hook-stdin-json-payload-includes-a-utf-8-bom-that-breaks-standard-json-parse-causing-security-guards-to-silently-degrade-to-allowing-commands-across-all-agent-channels/166794>\
**Category:** Bug Reports\
**Tags:** security, hooks, windows\
**Created:** [July 27, 2026, 5:46pm UTC](https://forum.cursor.com/t/on-windows-cursor-s-hook-stdin-json-payload-includes-a-utf-8-bom-that-breaks-standard-json-parse-causing-security-guards-to-silently-degrade-to-allowing-commands-across-all-agent-channels/166794 "2026-07-27T17:46:02Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dario\_Bublitz](https://sea3.discourse-cdn.com/cursor1/user_avatar/forum.cursor.com/dario_bublitz/32/115842_2.png) [@Dario\_Bublitz](https://forum.cursor.com/u/Dario_Bublitz)\
**Post date:** [July 27, 2026, 5:46pm UTC](https://forum.cursor.com/t/on-windows-cursor-s-hook-stdin-json-payload-includes-a-utf-8-bom-that-breaks-standard-json-parse-causing-security-guards-to-silently-degrade-to-allowing-commands-across-all-agent-channels/166794/1 "2026-07-27T17:46:02Z")

</div>

### **Where does the bug appear (feature/product)?**

Something else… — Workspace hooks (`.cursor/hooks.json`, `beforeShellExecution`)

**Describe the Bug**  
On Windows, the JSON payload delivered to hook scripts via stdin is prefixed  
with a UTF-8 BOM (`\uFEFF`). Any hook that does a standard  
`JSON.parse(readFileSync(0, "utf8"))` throws on it. If the script handles the  
parse error defensively (e.g. `catch { return {} }`), a security guard  
silently degrades to allow-everything — no error surfaces anywhere.

We initially chased a phantom “subagents bypass beforeShellExecution” bug;  
raw-logging stdin revealed the hook fires correctly on every channel (main  
agent AND Multitask subagents, each with its own `conversation_id`) and the  
payload is complete — it just starts with a BOM. So this is purely an  
encoding issue, not a lifecycle one.

**Steps to Reproduce**

1. Create `.cursor/hooks.json` with a `beforeShellExecution` hook pointing to  
a Node `.mjs` script.
2. In the script, log the raw stdin:  
`appendFileSync("log.txt", JSON.stringify(readFileSync(0, "utf8")))`  
and then `JSON.parse` it without stripping anything.
3. Ask the agent to run any shell command.
4. Inspect `log.txt`: the payload starts with `\uFEFF{`. The `JSON.parse`  
throws `SyntaxError: Unexpected token`.

Workaround that fixes it:

```js
const raw = readFileSync(0, "utf8").replace(/^\uFEFF/, "");

```

**Expected Behavior**  
The stdin payload should be plain UTF-8 JSON without a BOM (or the BOM should  
be documented so hook authors know to strip it). Given that hooks are used as  
security guardrails, a silently unparseable payload is a safety issue: the  
natural defensive `catch` turns the guard into allow-all.

**Operating System**  
Windows 10/11 (repo checkout on the Windows filesystem; also verified the  
same BOM from both PowerShell and WSL-side inspection)

**Version Information**

```auto
Cursor 3.13.10 (Windows 11)

```

**For AI issues: which model did you use?**  
N/A — not model-related (reproduced identically with the hook fired by  
main-agent and Multitask subagent sessions).

**Additional Information**  
The hook lifecycle itself works correctly on Windows: we verified with a  
controlled matrix that `beforeShellExecution` fires for the main agent and  
for Multitask background subagents, and that deny responses are respected on  
both channels once the BOM is stripped. The integrated (human) terminal  
correctly does not trigger hooks. Only the BOM prefix is the problem.

**Does this stop you from using Cursor?**  
No - Cursor works, but with this issue (though it can silently neutralize  
security-oriented hooks, so the impact is worse than it looks).

---

<div class="post-metadata">

**Author:** ![system](https://sea3.discourse-cdn.com/cursor1/user_avatar/forum.cursor.com/system/32/99069_2.png) [@system](https://forum.cursor.com/u/system)\
**Post date:** [July 27, 2026, 5:46pm UTC](https://forum.cursor.com/t/on-windows-cursor-s-hook-stdin-json-payload-includes-a-utf-8-bom-that-breaks-standard-json-parse-causing-security-guards-to-silently-degrade-to-allowing-commands-across-all-agent-channels/166794/2 "2026-07-27T17:46:11Z")

</div>

Hi there!

We detected that this may be a bug report, so we’ve moved your post to the **Bug Reports** category.

To help us investigate and fix this faster, could you edit your original post to include the details from the template below?

> **Bug Report Template - Click to expand**
>
> **Where does the bug appear (feature/product)?**
> 
> - Editor, Tab & Chat (autocomplete, Composer, in-editor agent)
> - Terminal & commands
> - Models, pricing & API keys (availability, Auto/Max, BYOK/Bedrock)
> - MCP & tools
> - Cloud Agents & Automations ([cursor.com/agents](http://cursor.com/agents), scheduled/event)
> - BugBot & Code Review
> - Cursor CLI
> - Cursor Mobile
> - Remote (SSH / Dev Containers / WSL)
> - Account, billing & login
> - Something else…
> 
> * * *
> 
> **Describe the Bug**  
> A clear and concise description of what the bug is.
> 
> * * *
> 
> **Steps to Reproduce**  
> How can you reproduce this bug? We have a much better chance at fixing issues if we can reproduce them!
> 
> 1. …
> 2. …
> 3. …
> 
> * * *
> 
> **Expected Behavior**  
> What is meant to happen here that isn’t working correctly?
> 
> * * *
> 
> **Screenshots / Screen Recordings**  
> If applicable, attach images or videos (.jpg, .png, .gif, .mp4, .mov)
> 
> * * *
> 
> **Operating System**
> 
> - Windows 10/11
> - MacOS
> - Linux
> 
> * * *
> 
> **Version Information**
> 
> - For Cursor IDE: Menu → About Cursor → Copy
> - For Cursor CLI: Run `agent about` in your terminal
> 
> ```auto
> IDE:
> Version: 2.xx.x
> VSCode Version: 1.105.1
> Commit: ......
> 
> CLI:
> CLI Version 2026.01.17-d239e66
> 
> ```
> 
> * * *
> 
> **For AI issues: which model did you use?**  
> Model name (e.g., Sonnet 4, Tab…)
> 
> * * *
> 
> **For AI issues: add Request ID with privacy disabled**  
> Request ID: f9a7046a-279b-47e5-ab48-6e8dc12daba1  
> For Background Agent issues, also post the ID: bc-…
> 
> * * *
> 
> **Additional Information**  
> Add any other context about the problem here.
> 
> * * *
> 
> **Does this stop you from using Cursor?**
> 
> - Yes - Cursor is unusable
> - Sometimes - I can sometimes use Cursor
> - No - Cursor works, but with this issue

The more details you provide, the easier it is for us to reproduce and fix the issue. Thanks!

---

<div class="post-metadata">

**Author:** ![deanrie](https://sea3.discourse-cdn.com/cursor1/user_avatar/forum.cursor.com/deanrie/32/1263_2.png) [@deanrie](https://forum.cursor.com/u/deanrie)\
**Post date:** [July 27, 2026, 6:16pm UTC](https://forum.cursor.com/t/on-windows-cursor-s-hook-stdin-json-payload-includes-a-utf-8-bom-that-breaks-standard-json-parse-causing-security-guards-to-silently-degrade-to-allowing-commands-across-all-agent-channels/166794/6 "2026-07-27T18:16:26Z")

</div>

Hey, thanks for the report. The diagnostics are great, and they’re fully confirmed. This is a bug on our side. On Windows, the payload really does get sent to the hook’s stdin with a UTF-8 BOM `\uFEFF` at the start, due to how PowerShell pipes text into a native command. The temp file with the payload is clean. The BOM shows up only at the piping step.

Your workaround is correct, so please keep it:

```js
const raw = readFileSync(0, "utf8").replace(/^\uFEFF/, "");

```

Also, `failClosed: true` is the right call for guard hooks. By default, `beforeShellExecution` is fail-open, so a swallowed parsing error silently degrades to allow-everything. You already found this. Just confirming it’s expected fail-open behavior, not a separate lifecycle bug, and that the main-agent and Multitask channels use the same path.

I’ve filed the bug internally, and I also noted that the hooks docs example currently hits this same issue on Windows. I can’t share an ETA for a fix yet. Once I have an update, I’ll reply in the thread.
