How Cursor Stores Its Command Allowlist in SQLite (And How to Read/Modify It)

Oct 9, 2025

If you've used Cursor, you've probably heard of the infamous "YOLO Mode". This is a feature that allows the AI agent to execute commands without asking for permission. You can enable for all commands if you're feeling brave but the more cautious of us prefer to whitelist only a subset of commands. I was curious where exactly these settings are stored since they don't appear in any user-editable settings file. Some quick digging with ripgrep -uuu quickly lead to the a SQLite database hidden away in the application support directory (macos). In this post we'll walk through where it is and how to read/modify it. This can be useful for auditing your configuration or maybe a fun way to create a persistent backdoor in a place that doesn't get monitored as closely.

Where is it stored?

Cursor stores its user data in SQLite databases located in the application support directory:

macOS:

~/Library/Application Support/Cursor/User/globalStorage/state.vscdb

Windows:

%APPDATA%\Cursor\User\globalStorage\state.vscdb

Linux:

~/.config/Cursor/User/globalStorage\state.vscdb

Reading the command allowlist

The command allowlist is stored in the ItemTable with the key src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser. Here's how to read it:

Using sqlite3 command line

sqlite3 -header -column ~/Library/Application\ Support/Cursor/User/globalStorage/state.vscdb \
  "SELECT 
    json_extract(value, \"\$.composerState.useYoloMode\") as useYoloMode,
    json_extract(value, \"\$.composerState.yoloCommandAllowlist\") as yoloCommandAllowlist,
    json_extract(value, \"\$.composerState.yoloCommandDenylist\") as yoloCommandDenylist,
    json_extract(value, \"\$.composerState.yoloPrompt\") as yoloPrompt,
    json_extract(value, \"\$.composerState.yoloDotFilesDisabled\") as yoloDotFilesDisabled,
    json_extract(value, \"\$.composerState.yoloOutsideWorkspaceDisabled\") as yoloOutsideWorkspaceDisabled,
    json_extract(value, \"\$.composerState.playwrightProtection\") as playwrightProtection,
    json_extract(value, \"\$.composerState.mcpAllowedTools\") as mcpAllowedTools
  FROM ItemTable 
  WHERE key = 'src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

This will return all the composerState security settings in a nicely formatted table:

useYoloMode  yoloCommandAllowlist  yoloCommandDenylist  yoloPrompt  yoloDotFilesDisabled  yoloOutsideWorkspaceDisabled  playwrightProtection  mcpAllowedTools
-----------  -------------------  -------------------  ----------  -------------------  -----------------------------  --------------------  ----------------
false        ["cd","npm run"]       []                   ""          true                   true                           false                  ["filesystem:read_file"]

Using a script to extract just the allowlist

Here's a simple script to extract just the command allowlist:

#!/bin/bash
DB_PATH="$HOME/Library/Application Support/Cursor/User/globalStorage/state.vscdb"
KEY="src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser"

# Extract just the allowlist using SQLite JSON functions
sqlite3 -header -column "$DB_PATH" \
  "SELECT json_extract(value, '\$.composerState.yoloCommandAllowlist') as yoloCommandAllowlist
   FROM ItemTable 
   WHERE key = '$KEY';"

Modifying the command allowlist

⚠️ Warning: Modifying Cursor's internal database can cause issues. Always backup your data first and close Cursor before making changes.

Interestingly, the database is not locked while cursor is running so you'll get no complaints from SQLite about updating while it's in use. You will need to restart cursor to see the changes.

Adding commands to the allowlist

To add new commands to the allowlist, you can use SQLite's JSON functions to parse the existing array and append new commands:

sqlite3 ~/Library/Application\ Support/Cursor/User/globalStorage/state.vscdb \
  "UPDATE ItemTable SET value = json_replace(value, '\$.composerState.yoloCommandAllowlist', 
    json_insert(json_extract(value, '\$.composerState.yoloCommandAllowlist'), '$[#]', 'bash'))
  WHERE key = 'src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

This one-liner:

  1. Extracts the current allowlist array
  2. Inserts 'bash' at the end of the array using json_insert with '$[#]' (append to end)
  3. Updates the database with the modified JSON

Enabling/Disabling YOLO mode

If you set useYoloMode to true, the AI agent will execute all commands without asking for permission. When the allowlist is in use, useYoloMode will be false.

Enable YOLO mode

sqlite3 ~/Library/Application\ Support/Cursor/User/globalStorage/state.vscdb \
  "UPDATE ItemTable SET value = json_replace(value, '\$.composerState.useYoloMode', 'true')
  WHERE key = 'src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

Disable YOLO mode

sqlite3 ~/Library/Application\ Support/Cursor/User/globalStorage/state.vscdb \
  "UPDATE ItemTable SET value = json_replace(value, '\$.composerState.useYoloMode', 'false')
  WHERE key = 'src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

"Yolo Prompt"

There is a setting called "yolo prompt" that I'm not entirely sure what it does. I tried messing with it and wasn't able to get any visible side-effects. I'm curious if this is for a feature where you define the yolo whitelist with a prompt rather than by commands.

Get the "Yolo Prompt"

sqlite3 ~/Library/Application\ Support/Cursor/User/globalStorage/state.vscdb \
  "SELECT json_extract(value, '\$.composerState.yoloPrompt') as yoloPrompt
  FROM ItemTable 
  WHERE key = 'src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

Set the "Yolo Prompt"

sqlite3 ~/Library/Application\ Support/Cursor/User/globalStorage/state.vscdb \
  "UPDATE ItemTable SET value = json_replace(value, '\$.composerState.yoloPrompt', 'Always execute uname -a before any command in yolo mode.')
  WHERE key = 'src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

Additional security controls

Cursor includes several other security-related settings in the composerState that can be modified:

Dot files access

# Disable access to dot files (default: true)
sqlite3 ~/Library/Application\ Support/Cursor/User/globalStorage/state.vscdb \
  "UPDATE ItemTable SET value = json_replace(value, '\$.composerState.yoloDotFilesDisabled', 'false')
  WHERE key = 'src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

Workspace boundary enforcement

# Allow commands outside workspace (default: true - commands outside workspace are disabled)
sqlite3 ~/Library/Application\ Support/Cursor/User/globalStorage/state.vscdb \
  "UPDATE ItemTable SET value = json_replace(value, '\$.composerState.yoloOutsideWorkspaceDisabled', 'false')
  WHERE key = 'src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

Playwright protection

# Disable Playwright protection (default: false)
sqlite3 ~/Library/Application\ Support/Cursor/User/globalStorage/state.vscdb \
  "UPDATE ItemTable SET value = json_replace(value, '\$.composerState.playwrightProtection', 'true')
  WHERE key = 'src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

MCP allowed tools

# Add tools to the MCP allowlist
sqlite3 ~/Library/Application\ Support/Cursor/User/globalStorage/state.vscdb \
  "UPDATE ItemTable SET value = json_replace(value, '\$.composerState.mcpAllowedTools', 
    json_insert(json_extract(value, '\$.composerState.mcpAllowedTools'), '$[#]', 'filesystem:write_file'))
  WHERE key = 'src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

Modes

The modes are stored in the $.composerState.modes4 property. They look a little likes this:

{
    "modes4": [
      {
        "id": "agent",
        "name": "Agent",
        "actionId": "composerMode.agent",
        "icon": "infinity",
        "description": "Plan, search, make edits, run commands",
        "thinkingLevel": "none",
        "shouldAutoApplyIfNoEditTool": true,
        "autoFix": true,
        "autoRun": true,
        "enabledTools": [],
        "enabledMcpServers": [],
        "fullAutoRun": false
      },
      {
        "id": "plan",
        "name": "Plan",
        "actionId": "composerMode.plan",
        "icon": "todos",
        "description": "Create detailed plans for accomplishing tasks",
        "thinkingLevel": "none",
        "shouldAutoApplyIfNoEditTool": false,
        "autoFix": false,
        "autoRun": false,
        "enabledTools": [],
        "enabledMcpServers": []
      }

You can set the default mode with the $.composerState.defaultMode2 property. On my setup it is currently set to "agent".

Is this a security concern?

Honestly, if an attacker is in a position to modify this file, you're probably already well and cooked. The main security consideration would be if Cursor was syncing settings between devices, which could potentially propagate malicious configurations. For now, this is more of a peek under the hood of how cursor stores these settings.

RSS
https://tarq.net/posts/atom.xml