v0.4.0-draft AI Drafted

Cursor Hardening Guide

DevOps Last updated: 2026-08-08

AI code editor security hardening for code privacy, MCP security, agent sandboxing, API key management, and workspace trust

Code Packs: Config
View:

Product Editions Covered: Cursor Free, Cursor Pro, Cursor Teams, Cursor Enterprise


Overview

Cursor is an AI-powered code editor built on VSCode that integrates large language models (LLMs) directly into the development workflow. As organizations adopt AI coding assistants, securing these tools becomes critical—they process proprietary source code, handle API credentials, connect to multiple AI providers, and increasingly operate as autonomous agents capable of executing terminal commands, modifying files, and interacting with external services via MCP servers.

The threat landscape for AI code editors evolved rapidly in 2025-2026. Seven CVEs were assigned to Cursor in 2025 alone—including remote code execution via MCP prompt injection (CurXecute), persistent team-wide compromise through poisoned MCP configurations (MCPoison), sandbox escapes via shell builtins (NomShub), and case-sensitivity bypasses enabling sensitive file overwrites. A malicious extension on the Open VSX registry led to a confirmed $500,000 cryptocurrency theft. Security researchers demonstrated that invisible Unicode characters in .cursorrules files can weaponize AI code generation across entire teams.

This guide provides comprehensive hardening controls informed by vendor documentation, CVE analysis, security researcher disclosures, and industry frameworks including the OWASP Top 10 for LLM Applications (2025), the OWASP Top 10 for Agentic Applications (2026), NIST AI RMF, NIST SP 800-218A, and MITRE ATLAS v5.

Intended Audience

  • Security engineers evaluating AI coding tools
  • DevOps/Platform engineers managing developer environments
  • Engineering managers responsible for tooling security
  • Compliance teams assessing data privacy for AI tools

How to Use This Guide

  • L1 (Crawl): Essential controls for all organizations using Cursor
  • L2 (Walk): Enhanced controls for organizations with sensitive codebases
  • L3 (Run): Strictest controls for regulated industries or high-security environments

Scope

This guide covers Cursor-specific security configurations including AI privacy settings, MCP server security, agent sandbox controls, API key management, rules file integrity, code privacy controls, workspace trust, extension supply chain security, and organizational policies. General VSCode security and operating system hardening are out of scope.

Why This Guide Exists

No CIS Benchmark or equivalent standard exists for AI code editors. As AI coding assistants become mission-critical development tools with autonomous agent capabilities, securing them is essential to:

  • Prevent proprietary code leakage to third-party AI providers
  • Protect API keys and credentials from exposure via AI context
  • Defend against prompt injection attacks through MCP servers, rules files, and repository content
  • Control autonomous agent actions (file writes, terminal execution, network access)
  • Audit AI usage and code generation for compliance
  • Manage extension supply chain risks in AI-augmented workflows
  • Meet emerging regulatory requirements (EU AI Act, NIST AI RMF)

Table of Contents

  1. Authentication & Access Controls
  2. AI Privacy & Data Controls
  3. API Key & Credential Management
  4. MCP Server Security
  5. Agent & Sandbox Security
  6. Rules File & Project Security
  7. Workspace Trust & Code Security
  8. Extension & Integration Security
  9. Network & Telemetry Controls
  10. Monitoring & Audit Logging
  11. Organization & Team Controls

1. Authentication & Access Controls

1.1 Enforce Account Authentication for All Users

Profile Level: L1 (Crawl) NIST 800-53: IA-2

Description

Require all developers to authenticate with a Cursor account instead of using the editor anonymously. This enables audit logging, usage tracking, and centralized policy enforcement.

Rationale

Why This Matters:

  • Anonymous usage prevents attribution of AI-generated code
  • Account-based access enables usage monitoring and anomaly detection
  • Required for enforcing organizational policies and compliance

Attack Prevented: Unauthorized tool usage, lack of accountability

Prerequisites

  • Cursor account for each developer
  • Decision on authentication method (email/password, GitHub OAuth, Google OAuth)
  • Communication plan for mandatory account creation

ClickOps Implementation

Step 1: Require Login

  1. Open Cursor → Settings (Cmd/Ctrl + ,)
  2. Navigate to: Cursor Settings
  3. Ensure Sign in to Cursor is completed
  4. For team deployments: Use Cursor Teams or Enterprise to enforce authentication

Step 2: Configure Authentication Method

  1. Go to: https://cursor.com/settings
  2. Choose authentication provider:
    • Email/Password: Basic authentication
    • GitHub OAuth: Recommended for developer workflows
    • Google Workspace: Recommended for G Suite organizations
  3. Complete authentication flow

Step 3: Verify Authentication Status

  1. In Cursor, check bottom-right status bar for account email
  2. Verify account is active and authenticated

Time to Complete: ~5 minutes per user

Validation & Testing

  1. Attempt to use Cursor features without authentication
  2. Verify AI features require authenticated account
  3. Confirm account shows in Cursor status bar

Expected result: All Cursor features require authenticated account

Operational Impact

Aspect Impact Level Details
User Experience Low One-time authentication flow
Development Workflow None No workflow changes after authentication
Maintenance Burden Low Occasional re-authentication required
Rollback Difficulty Easy Sign out from account

Compliance Mappings

Framework Control ID Control Description
SOC 2 CC6.1 User identification and authentication
NIST 800-53 IA-2 Identification and authentication
ISO 27001 A.9.2.1 User registration and de-registration

1.2 Enable Multi-Factor Authentication (MFA)

Profile Level: L2 (Walk) NIST 800-53: IA-2(1)

Description

Require MFA for Cursor account authentication to prevent account takeover via compromised credentials.

Rationale

Why This Matters:

  • Developer accounts access proprietary source code
  • Cursor accounts may have API keys for OpenAI, Anthropic, and other providers
  • Account compromise could leak code via AI chat history
  • StackAware researchers demonstrated an account takeover chain via login link interception

Attack Prevented: Credential stuffing, password reuse attacks, phishing, login link interception

ClickOps Implementation

Step 1: Enable MFA on Cursor Account

  1. Visit: https://cursor.com/settings/security
  2. Navigate to Multi-Factor Authentication
  3. Click Enable MFA
  4. Choose method:
    • Authenticator App (TOTP): Recommended (Authy, 1Password, Google Authenticator)
    • SMS: Available but less secure
  5. Scan QR code with authenticator app
  6. Enter verification code
  7. Save recovery codes in secure location (password manager)

Step 2: Verify MFA Enforcement

  1. Sign out of Cursor
  2. Sign back in
  3. Verify MFA prompt appears after password

Time to Complete: ~10 minutes

Validation & Testing

  1. Attempt login with only password - should prompt for MFA
  2. Test authenticator app generates valid codes
  3. Verify recovery codes work for MFA bypass

Expected result: All logins require MFA verification

Compliance Mappings

Framework Control ID Control Description
SOC 2 CC6.1 Multi-factor authentication
NIST 800-53 IA-2(1) Multi-factor authentication
PCI DSS 8.3 MFA for all access

1.3 Configure SSO with SAML/OIDC (Enterprise)

Profile Level: L2 (Walk) NIST 800-53: IA-2, IA-8

Description

Integrate Cursor with your identity provider (IdP) via SAML 2.0 or OIDC for centralized authentication. Enforce SSO-only login to prevent local credential usage.

Rationale

Why This Matters:

  • Centralizes authentication lifecycle — offboarding in the IdP immediately revokes Cursor access
  • Enables conditional access policies (device compliance, location-based restrictions)
  • Eliminates password reuse risk for Cursor accounts
  • Required for SCIM provisioning (Control 1.4)

Attack Prevented: Orphaned accounts, credential reuse, unauthorized access after offboarding

Prerequisites

  • Cursor Enterprise plan
  • IdP with SAML 2.0 support (Okta, Microsoft Entra ID, Google Workspace, OneLogin)

ClickOps Implementation

Step 1: Configure SSO in Cursor Admin Dashboard

  1. Navigate to: https://cursor.com/dashboard → SettingsSingle Sign-On (SSO)
  2. Select your IdP type (SAML 2.0 or OIDC)
  3. Enter IdP metadata URL or upload metadata XML
  4. Configure attribute mapping:
    • email → user email
    • name → display name
  5. Save configuration

Step 2: Configure IdP Side

  1. In your IdP, create a new SAML/OIDC application for Cursor
  2. Set ACS URL and Entity ID provided by Cursor dashboard
  3. Assign users/groups to the Cursor application

Step 3: Enforce SSO-Only Authentication

  1. In Cursor dashboard: Enable Require SSO for all team members
  2. This disables local login for all team members

Step 4: Verify SSO Flow

  1. Sign out of Cursor
  2. Attempt sign in — should redirect to IdP login
  3. Complete IdP authentication
  4. Verify automatic redirect back to Cursor with active session

Time to Complete: ~30 minutes

Validation & Testing

  1. Verify SSO login flow completes without errors
  2. Test that local login is blocked when SSO is enforced
  3. Offboard a test user in IdP — verify Cursor access is revoked
  4. Verify JIT (Just-in-Time) provisioning creates new user accounts on first SSO login

Expected result: All team members authenticate exclusively through SSO

Compliance Mappings

Framework Control ID Control Description
SOC 2 CC6.1 Centralized identity management
NIST 800-53 IA-2 Identification and authentication
NIST 800-53 IA-8 Identification and authentication (non-org users)
ISO 27001 A.9.2.1 User registration and de-registration

1.4 Enable SCIM Provisioning (Enterprise)

Profile Level: L2 (Walk) NIST 800-53: AC-2

Description

Enable SCIM 2.0 to automate user lifecycle management (provisioning, deprovisioning, group sync) between your IdP and Cursor.

Rationale

Why This Matters:

  • Automating deprovisioning ensures no orphaned accounts retain access to AI chat history or cached code context
  • Group-based role assignment enforces RBAC consistently
  • Reduces manual administration burden for large teams

Attack Prevented: Orphaned accounts, excessive access, manual provisioning errors

Prerequisites

  • Cursor Enterprise plan with SSO enabled — Cursor documents SCIM 2.0 provisioning as “available on Enterprise plans with SSO enabled.” SSO (Control 1.3) is a hard dependency, not a recommendation
  • IdP with SCIM 2.0 support

ClickOps Implementation

Step 1: Generate SCIM Token

  1. In Cursor dashboard → SettingsSCIM Provisioning
  2. Generate a SCIM bearer token
  3. Copy the SCIM endpoint URL and token

Step 2: Configure IdP SCIM Client

  1. In your IdP, open the Cursor SAML application settings
  2. Enable SCIM provisioning
  3. Enter the SCIM endpoint URL and bearer token from Step 1
  4. Configure provisioning actions:
    • Create Users: Enabled
    • Update User Attributes: Enabled
    • Deactivate Users: Enabled
  5. Map IdP groups to Cursor roles. Cursor teams have three roles: Members, Admins, and Unpaid Admins — the last exists so an administrator can manage the team without consuming a paid seat, which is the correct assignment for IT or security staff who administer Cursor but do not write code in it

Step 3: Test Provisioning

  1. Assign a test user to the Cursor application in IdP
  2. Verify user appears in Cursor dashboard within minutes
  3. Remove the test user from IdP
  4. Verify user is deactivated in Cursor

Time to Complete: ~30 minutes

Compliance Mappings

Framework Control ID Control Description
SOC 2 CC6.2 Prior to issuing access, authorization is verified
NIST 800-53 AC-2 Account management
ISO 27001 A.9.2.6 Removal or adjustment of access rights

2. AI Privacy & Data Controls

2.1 Enable Privacy Mode for Sensitive Codebases

Profile Level: L1 (Crawl) NIST 800-53: SC-4

Description

Configure Cursor’s Privacy Mode to prevent code from being stored or used for training by third-party AI providers. When enabled, Cursor has zero data retention agreements with OpenAI, Anthropic, Google, xAI, and Fireworks. Code enters volatile memory for processing and is discarded.

Rationale

Why This Matters:

  • Without Privacy Mode, Cursor may store codebase data, prompts, and code snippets to improve AI features and train models
  • For accounts created after October 15, 2025, prompts may be shared with OpenAI when using their models
  • Fireworks (Cursor’s inference provider) may collect prompts to improve inference speed
  • Privacy Mode routes requests through separate server replicas where all logging functions are no-ops
  • Compliance regulations (GDPR, HIPAA, SOC 2) may prohibit cloud AI processing of sensitive code

Attack Prevented: Data leakage to third-party AI providers, unauthorized code retention, training data contamination

Real-World Context:

  • Samsung banned ChatGPT after engineers leaked sensitive code (April 2023)
  • Over 50% of Cursor users already enable Privacy Mode, indicating widespread concern
  • Internal repositories are 6x more likely to contain hardcoded secrets than public ones

Prerequisites

  • Classification of codebases (public, internal, confidential)
  • Decision on which repos require Privacy Mode
  • Communication to developers about Privacy Mode policies

ClickOps Implementation

Step 1: Enable Privacy Mode Globally

  1. Open Cursor → Settings (Cmd/Ctrl + ,)
  2. Navigate to: Cursor SettingsGeneralPrivacy Mode
  3. Enable: Privacy Mode
    • When enabled, zero data retention agreements apply with all AI providers
    • Code enters volatile memory only for processing, then is discarded
    • Cursor’s servers run separate replicas where logging is disabled
  4. For Teams/Enterprise: Enable org-wide enforcement in admin dashboard to prevent individual override

Step 2: Request US-only data residency (Enterprise, L2/L3)

Privacy Mode governs retention; data residency governs location. Where your obligations are jurisdictional rather than retention-based, Privacy Mode alone does not satisfy them.

  1. Cursor documents US-only data residency as “available to Enterprise customers and is enabled per team” — request it through your account team, not from the dashboard
  2. Plan the lead time: Cursor says to “plan for up to two weeks from the time the request comes in”
  3. Budget for the cost: it carries a “10% uplift on Model pricing for eligible Models”
  4. Understand the coverage before relying on it. Residency applies to inference, data processing, and storage across supported features including Cloud Agents, autocomplete, and semantic search — but only a specific set of model families run in-region. Cursor lists these as GPT (gpt-*), Claude 4.6 and above, Gemini 2.5 Flash, Composer, and Grok 4.5. A model outside that list will not run in-region, so pair residency with model restrictions (2.2) or developers can silently select their way out of it
  5. Expect added latency for users travelling outside the US, since requests still route to US-only infrastructure

Step 3: Gate restricted models that carry retention obligations

Some models are withheld from Privacy Mode and Enterprise users until an admin explicitly approves them, because the provider retains inputs and outputs. Cursor documents Claude Fable 5 as requiring such approval: Anthropic “stores its inputs and outputs to run automatic and human harm-prevention reviews,” and states “this data is not used for training or product improvement.” Approval applies organization-wide.

  1. Treat any such approval as a data-flow decision, not a model-availability decision — approving it changes what leaves your organization under Privacy Mode
  2. If you approve it, narrow the exposure: Cursor notes that “Enterprise admins can still limit which user groups can select the model,” so scope it to the teams that need it rather than the whole organization
  3. Record the approval and its scope in your AI vendor register, since it is an exception to the zero-retention posture the rest of this control establishes

Step 4: Configure Per-Workspace Privacy

For granular control, add privacy settings to workspace configuration:

Code Pack: Config
hth-cursor-2.01-privacy-mode-config.sh View source on GitHub ↗
# .vscode/settings.json — per-workspace Privacy Mode enforcement
cat > .vscode/settings.json <<'SETTINGS'
{
  "cursor.general.privacyMode": "enabled",
  "cursor.general.enableShadowWorkspace": false,
  "cursor.general.allowAnonymousUsage": false
}
SETTINGS
echo "Privacy Mode workspace settings written to .vscode/settings.json"
# Verify Privacy Mode is active across all workspace settings files
echo "=== Checking for Privacy Mode in settings files ==="
for f in \
  "${HOME}/Library/Application Support/Cursor/User/settings.json" \
  "${HOME}/.config/Cursor/User/settings.json" \
  ".vscode/settings.json"; do
  if [ -f "$f" ]; then
    PRIVACY=$(grep -o '"cursor.general.privacyMode"[[:space:]]*:[[:space:]]*"[^"]*"' "$f" 2>/dev/null || echo "not set")
    echo "  $f: $PRIVACY"
  fi
done

echo ""
echo "=== Checking network traffic to AI provider APIs ==="
echo "Run one of these to verify no code leaks to cloud providers:"
echo "  macOS:  lsof -i -n -P | grep -i cursor | grep -E '(openai|anthropic)'"
echo "  Linux:  ss -tnp | grep cursor | grep -E '(openai|anthropic)'"

Step 5: Verify Privacy Mode Active

  1. Check Cursor status bar for Privacy Mode indicator
  2. Run the verification commands from the Code Pack

Time to Complete: ~5 minutes per workspace

Validation & Testing

Code Pack: Config
hth-cursor-2.01-privacy-mode-config.sh View source on GitHub ↗
# .vscode/settings.json — per-workspace Privacy Mode enforcement
cat > .vscode/settings.json <<'SETTINGS'
{
  "cursor.general.privacyMode": "enabled",
  "cursor.general.enableShadowWorkspace": false,
  "cursor.general.allowAnonymousUsage": false
}
SETTINGS
echo "Privacy Mode workspace settings written to .vscode/settings.json"
# Verify Privacy Mode is active across all workspace settings files
echo "=== Checking for Privacy Mode in settings files ==="
for f in \
  "${HOME}/Library/Application Support/Cursor/User/settings.json" \
  "${HOME}/.config/Cursor/User/settings.json" \
  ".vscode/settings.json"; do
  if [ -f "$f" ]; then
    PRIVACY=$(grep -o '"cursor.general.privacyMode"[[:space:]]*:[[:space:]]*"[^"]*"' "$f" 2>/dev/null || echo "not set")
    echo "  $f: $PRIVACY"
  fi
done

echo ""
echo "=== Checking network traffic to AI provider APIs ==="
echo "Run one of these to verify no code leaks to cloud providers:"
echo "  macOS:  lsof -i -n -P | grep -i cursor | grep -E '(openai|anthropic)'"
echo "  Linux:  ss -tnp | grep cursor | grep -E '(openai|anthropic)'"

Expected result: No code sent to external AI services for retention or training

Monitoring & Maintenance

Alert on Privacy Mode Bypass:

  • Monitor for network connections to api.openai.com, api.anthropic.com that bypass Cursor’s proxy
  • Use endpoint security tools to detect unauthorized AI API calls

Important caveat: Regardless of model selection, some requests may route through OpenAI or Anthropic for background summarization tasks. In Privacy Mode, these still have zero data retention, but the routing itself is worth noting for strict data flow requirements.

Maintenance schedule:

  • Weekly: Verify Privacy Mode still enabled in settings
  • Monthly: Audit developer workspaces for privacy settings compliance
  • Quarterly: Review Privacy Mode policy effectiveness

Operational Impact

Aspect Impact Level Details
Developer Productivity Low AI features remain functional; only data retention changes
Code Quality None AI assistance quality is identical
Maintenance Burden Low Once configured, no ongoing maintenance
Rollback Difficulty Easy Disable Privacy Mode in settings

Compliance Mappings

Framework Control ID Control Description
SOC 2 CC6.7 Data transmission controls
NIST 800-53 SC-4 Information in shared system resources
GDPR Article 28 Processor obligations (AI providers as processors)
ISO 27001 A.13.2.1 Information transfer policies
NIST AI RMF GOVERN 1.7 AI data governance policies
OWASP LLM LLM02 Sensitive information disclosure

2.2 Govern Model Selection with Cursor Router

Profile Level: L2 (Walk) NIST 800-53: SC-7, SA-9

Description

Cursor Router (shipped 2026-07-22) automatically selects an underlying model for each request. It is the current surface through which an administrator governs which models a team may reach. Cursor documents that admins can “enable the router per team or group, restrict which optimization modes members can use, set the default mode, and allow or block underlying models,” with “soft and hard enforcement options for standardizing on Auto.” The three optimization modes are Cost, Balance, and Intelligence.

Rationale

Why This Matters:

  • The router is on by default for Teams plans. If your organization is on Teams and has not configured it, model selection is already being made automatically on your behalf — the default is not “no routing,” it is “routing you did not configure”
  • The routed model is hidden from the user by default (Cursor notes the routed model “can be displayed or hidden (hidden by default)”), so a developer cannot tell you which provider processed a given request unless an admin turns the display on. That is a material gap for anyone who has to evidence data flows to an auditor
  • Different underlying models carry different retention, residency, and training postures — some are restricted models requiring explicit admin approval (see 2.1). Allow/block at the router is where those decisions become enforceable rather than advisory
  • Model choice is also a residency decision: US-only data residency covers only a documented subset of model families (2.1), so unrestricted model selection can route a request out of the region you paid to stay in
  • Soft enforcement standardises behaviour while leaving an escape hatch; hard enforcement removes it. Choose deliberately rather than inheriting the default

Attack Prevented: Silent routing of proprietary code to an unvetted or non-approved model provider, circumvention of data-residency and zero-retention commitments through developer model selection, and loss of auditable data-flow evidence when the processing model is hidden by default

Prerequisites

  • Cursor Teams or Enterprise. Cursor states the router “is on by default for Teams plans,” and that Enterprise admins can enable it from the dashboard.

ClickOps Implementation

Step 1: Establish the current state

  1. Open the Cursor admin dashboard and check whether the router is enabled for each team or group
  2. On a Teams plan, assume it is on until you confirm otherwise
  3. Record which optimization modes are currently available to members and which is the default

Step 2: Make the routed model visible

  1. Turn on display of the routed model so developers and auditors can see which model served a request
  2. Leaving this hidden is defensible for a consumer product and indefensible for a regulated one — if you must evidence where code was processed, you need the model surfaced

Step 3: Allow or block underlying models

  1. Block models your vendor-review process has not approved
  2. Where US-only data residency is in force (2.1), block model families that Cursor does not run in-region, or residency is bypassable by model choice
  3. Keep restricted models that require explicit retention approval blocked until that approval is recorded

Step 4: Constrain modes and set enforcement

  1. Restrict which optimization modes members may select — Cost, Balance, or Intelligence
  2. Set the default mode explicitly rather than accepting the product default
  3. Choose soft enforcement where you want a standard with an override, or hard enforcement where the standard must hold. Document which you chose and why

Step 5: Scope per team or group

  1. Apply stricter model and mode restrictions to teams working on regulated or highest-sensitivity code
  2. Re-review after each Cursor changelog entry that touches routing — this is a fast-moving surface

Validation & Testing

  1. As a non-admin member, confirm blocked models are unavailable
  2. Confirm the routed model is displayed in the UI after enabling display
  3. Where hard enforcement is set, confirm a member cannot switch away from the standardised mode
  4. Confirm restrictions apply to the correct teams or groups, not just at the organization root

BYOK note: Where developers can supply their own provider API keys, model restrictions configured in Cursor do not govern that traffic. Treat BYOK as a separate decision and disable it for teams under model governance. (BYOK behaviour under Router was not re-verified against current vendor documentation in the 2026-08 pass.)

Compliance Mappings

Framework Control ID Control Description
SOC 2 CC9.2 Third-party vendor management
NIST 800-53 SA-9 External system services
NIST 800-53 SC-7 Boundary protection
OWASP LLM LLM03 Supply chain vulnerabilities
NIST AI RMF GOVERN 1.7 AI data governance policies

2.3 Configure .cursorignore for Sensitive Files

Profile Level: L1 (Crawl) NIST 800-53: AC-3, SC-4

Description

Create a .cursorignore file to exclude sensitive files and directories from being sent to Cursor’s servers for AI processing, indexing, or embedding. This is a critical data boundary control.

Rationale

Why This Matters:

  • Cursor sends code context (recently viewed files, surrounding code) to AI providers on every keystroke for Tab completions
  • Codebase indexing uploads code chunks for embedding computation
  • Without .cursorignore, secrets, credentials, and proprietary configuration may be included in AI context
  • .cursorignore provides a hard block — AI cannot see excluded files even if explicitly referenced

Known Limitation: .cursorignore is described as “best-effort” by Cursor. Bugs may allow ignored files through in certain cases (see GHSA-vhc2-fjv4-wqch). Use .cursorignore as defense-in-depth alongside secret scanning and Privacy Mode, not as a sole control.

Attack Prevented: Credential leakage via AI context, sensitive data exposure to AI providers

ClickOps Implementation

Step 1: Create .cursorignore File

Add a .cursorignore file to your project root:

Code Pack: Config
hth-cursor-2.03-cursorignore-template.sh View source on GitHub ↗
# Create a comprehensive .cursorignore file to exclude sensitive files from AI context
cat > .cursorignore <<'IGNORE'
# === Credentials & Secrets ===
.env
.env.*
.env.local
.env.production
**/.env
**/secrets/
**/credentials/
*.pem
*.key
*.p12
*.pfx
*.jks
id_rsa*
id_ed25519*
*.keystore

# === Cloud & Infrastructure Configs ===
.aws/
.azure/
.gcloud/
kubeconfig*
terraform.tfstate*
terraform.tfvars
*.auto.tfvars

# === Internal Configuration ===
**/config/production.*
**/config/secrets.*
docker-compose.override.yml

# === Cursor / IDE Configuration ===
.cursor/mcp.json
.vscode/launch.json

# === Compliance & Legal ===
**/compliance/
**/legal/
**/audit/
IGNORE

echo ".cursorignore written with sensitive file exclusions"
# Verify .cursorignore is present and covers critical patterns
echo "=== .cursorignore Audit ==="
if [ ! -f .cursorignore ]; then
  echo "FAIL: .cursorignore not found in project root"
  exit 1
fi

REQUIRED_PATTERNS=(".env" "*.pem" "*.key" "id_rsa" "terraform.tfstate" ".aws/")
MISSING=0
for pattern in "${REQUIRED_PATTERNS[@]}"; do
  if ! grep -qF "$pattern" .cursorignore; then
    echo "  MISSING: $pattern not in .cursorignore"
    MISSING=$((MISSING + 1))
  fi
done

if [ "$MISSING" -eq 0 ]; then
  echo "PASS: All critical patterns present in .cursorignore"
else
  echo "WARN: $MISSING critical patterns missing from .cursorignore"
fi

Step 2: Also Create .cursorindexingignore (Optional)

  • .cursorignore — hard block from both AI access and indexing
  • .cursorindexingignore — excludes from indexing only; files remain accessible to AI features if explicitly referenced

Use .cursorignore for secrets and credentials. Use .cursorindexingignore for large non-sensitive files (vendor directories, build artifacts).

Step 3: Commit to Repository

  1. Add .cursorignore to version control
  2. Standardize across all organizational repositories

Time to Complete: ~10 minutes

Validation & Testing

Code Pack: Config
hth-cursor-2.03-cursorignore-template.sh View source on GitHub ↗
# Create a comprehensive .cursorignore file to exclude sensitive files from AI context
cat > .cursorignore <<'IGNORE'
# === Credentials & Secrets ===
.env
.env.*
.env.local
.env.production
**/.env
**/secrets/
**/credentials/
*.pem
*.key
*.p12
*.pfx
*.jks
id_rsa*
id_ed25519*
*.keystore

# === Cloud & Infrastructure Configs ===
.aws/
.azure/
.gcloud/
kubeconfig*
terraform.tfstate*
terraform.tfvars
*.auto.tfvars

# === Internal Configuration ===
**/config/production.*
**/config/secrets.*
docker-compose.override.yml

# === Cursor / IDE Configuration ===
.cursor/mcp.json
.vscode/launch.json

# === Compliance & Legal ===
**/compliance/
**/legal/
**/audit/
IGNORE

echo ".cursorignore written with sensitive file exclusions"
# Verify .cursorignore is present and covers critical patterns
echo "=== .cursorignore Audit ==="
if [ ! -f .cursorignore ]; then
  echo "FAIL: .cursorignore not found in project root"
  exit 1
fi

REQUIRED_PATTERNS=(".env" "*.pem" "*.key" "id_rsa" "terraform.tfstate" ".aws/")
MISSING=0
for pattern in "${REQUIRED_PATTERNS[@]}"; do
  if ! grep -qF "$pattern" .cursorignore; then
    echo "  MISSING: $pattern not in .cursorignore"
    MISSING=$((MISSING + 1))
  fi
done

if [ "$MISSING" -eq 0 ]; then
  echo "PASS: All critical patterns present in .cursorignore"
else
  echo "WARN: $MISSING critical patterns missing from .cursorignore"
fi

Expected result: All critical patterns present and sensitive files excluded from AI context

Compliance Mappings

Framework Control ID Control Description
SOC 2 CC6.1 Logical access controls
NIST 800-53 AC-3 Access enforcement
NIST 800-53 SC-4 Information in shared resources
OWASP LLM LLM02 Sensitive information disclosure

2.4 Enable Local AI Models (L3 Maximum Security)

Profile Level: L3 (Run) NIST 800-53: SC-4, SC-7

Description

Configure Cursor to use only local AI models (running on-premises or on developer machines) instead of cloud-based AI services. This provides maximum code privacy — zero code leaves the organization’s network.

Rationale

Why This Matters:

  • Zero code leaves the organization’s network
  • Complete control over model and data processing
  • Meets strictest compliance requirements (defense, healthcare, financial)
  • Removes dependence on every upstream commitment — retention agreements, residency scope, and per-model approvals all become moot when inference never leaves your infrastructure

Attack Prevented: Any exfiltration of source code, prompts, or embeddings to a third-party inference provider — including routes that bypass Privacy Mode or model restrictions, such as developer-supplied provider keys or a model family outside the data-residency scope

Use Cases:

  • Government contractors with classified code
  • Healthcare orgs processing PHI/ePHI
  • Financial institutions with proprietary trading algorithms

ClickOps Implementation

Step 1: Install Local Model Backend

Options:

  • Ollama: Local LLM runtime (supports CodeLlama, Qwen2.5-Coder, DeepSeek-Coder, etc.)
  • LM Studio: Local model management with OpenAI-compatible API
  • Custom OpenAI-compatible API: Self-hosted models (vLLM, TGI)

Step 2: Configure Cursor to Use Local Model

  1. Open Cursor → Settings
  2. Navigate to: ModelsOpenAI API Key
  3. Set custom base URL pointing to local endpoint (e.g., http://localhost:11434/v1)
  4. Disable all cloud AI providers

Step 3: Verify Local Model Usage

  1. Use Cursor AI chat
  2. Check network traffic — should only connect to localhost
  3. Verify no external API calls

Time to Complete: ~1 hour (model download + configuration)

Performance Considerations

Model Parameters RAM Required Performance Use Case
Qwen2.5-Coder 7B 8 GB Fast, good quality Quick completions
DeepSeek-Coder-V2 16B 16 GB Balanced General development
Qwen2.5-Coder 32B 32 GB+ Slower, high quality Complex code generation
CodeLlama 70B 64 GB+ Slow, highest quality Critical code review

Compliance Mappings

Framework Control ID Control Description
NIST 800-53 SC-4 Information remnants
ITAR Data Sovereignty Code never leaves jurisdiction
FedRAMP SC-7 Boundary protection
NIST AI RMF GOVERN 1.4 AI deployment controls

3. API Key & Credential Management

3.1 Use Environment Variables for API Keys (Never Hardcode)

Profile Level: L1 (Crawl) NIST 800-53: IA-5(1)

Description

Store Cursor AI provider API keys in environment variables or secure credential stores, never hardcoded in settings files committed to version control.

Rationale

Why This Matters:

  • API keys in committed files leak to version control history
  • Cursor settings files may sync to cloud or backups
  • Hardcoded keys are difficult to rotate
  • Developers using AI tools leak secrets at 2x the baseline rate

Attack Prevented: API key exposure via Git history, backup theft

ClickOps Implementation

Step 1: Remove Hardcoded API Keys from Settings

  1. Check Cursor settings for hardcoded keys:
Code Pack: Config
hth-cursor-3.01-api-key-env-setup.sh View source on GitHub ↗
# INSECURE: Never hardcode API keys in Cursor settings files
# This is an example of what to SEARCH FOR and REMOVE:
#   "cursor.openai.apiKey": "sk-proj-abc123..."
#   "cursor.anthropic.apiKey": "sk-ant-abc123..."
# Add API keys as environment variables in your shell profile
# For zsh (default on macOS):
cat >> ~/.zshrc <<'ENVVARS'

# Cursor AI Provider API Keys (rotate quarterly — see HTH 3.2)
export OPENAI_API_KEY="sk-proj-YOUR-KEY-HERE"
export ANTHROPIC_API_KEY="sk-ant-YOUR-KEY-HERE"
ENVVARS

source ~/.zshrc
echo "API keys added to ~/.zshrc as environment variables"
# Verify no hardcoded API keys exist in Cursor settings files
echo "=== Scanning for hardcoded API keys in Cursor settings ==="
SETTINGS_PATHS=(
  "${HOME}/Library/Application Support/Cursor/User/settings.json"
  "${HOME}/.config/Cursor/User/settings.json"
  ".vscode/settings.json"
)

FOUND=0
for f in "${SETTINGS_PATHS[@]}"; do
  if [ -f "$f" ]; then
    if grep -qE '(sk-proj-|sk-ant-|OPENAI_API_KEY|ANTHROPIC_API_KEY)' "$f" 2>/dev/null; then
      echo "  FAIL: Hardcoded key found in $f"
      FOUND=$((FOUND + 1))
    fi
  fi
done

if [ "$FOUND" -eq 0 ]; then
  echo "  PASS: No hardcoded API keys found in settings files"
fi

# Also check git history for accidentally committed keys
echo ""
echo "=== Checking git history for leaked keys ==="
if command -v git &>/dev/null && git rev-parse --is-inside-work-tree &>/dev/null; then
  LEAKED=$(git log --all -p 2>/dev/null | grep -cE '(sk-proj-|sk-ant-)[A-Za-z0-9]{20,}' || echo "0")
  if [ "$LEAKED" -gt 0 ]; then
    echo "  FAIL: $LEAKED potential API key(s) found in git history"
    echo "  ACTION: Rotate keys immediately and use git-filter-repo to purge"
  else
    echo "  PASS: No API keys found in git history"
  fi
fi
  1. Remove any hardcoded API keys

Step 2: Use Environment Variables

Code Pack: Config
hth-cursor-3.01-api-key-env-setup.sh View source on GitHub ↗
# INSECURE: Never hardcode API keys in Cursor settings files
# This is an example of what to SEARCH FOR and REMOVE:
#   "cursor.openai.apiKey": "sk-proj-abc123..."
#   "cursor.anthropic.apiKey": "sk-ant-abc123..."
# Add API keys as environment variables in your shell profile
# For zsh (default on macOS):
cat >> ~/.zshrc <<'ENVVARS'

# Cursor AI Provider API Keys (rotate quarterly — see HTH 3.2)
export OPENAI_API_KEY="sk-proj-YOUR-KEY-HERE"
export ANTHROPIC_API_KEY="sk-ant-YOUR-KEY-HERE"
ENVVARS

source ~/.zshrc
echo "API keys added to ~/.zshrc as environment variables"
# Verify no hardcoded API keys exist in Cursor settings files
echo "=== Scanning for hardcoded API keys in Cursor settings ==="
SETTINGS_PATHS=(
  "${HOME}/Library/Application Support/Cursor/User/settings.json"
  "${HOME}/.config/Cursor/User/settings.json"
  ".vscode/settings.json"
)

FOUND=0
for f in "${SETTINGS_PATHS[@]}"; do
  if [ -f "$f" ]; then
    if grep -qE '(sk-proj-|sk-ant-|OPENAI_API_KEY|ANTHROPIC_API_KEY)' "$f" 2>/dev/null; then
      echo "  FAIL: Hardcoded key found in $f"
      FOUND=$((FOUND + 1))
    fi
  fi
done

if [ "$FOUND" -eq 0 ]; then
  echo "  PASS: No hardcoded API keys found in settings files"
fi

# Also check git history for accidentally committed keys
echo ""
echo "=== Checking git history for leaked keys ==="
if command -v git &>/dev/null && git rev-parse --is-inside-work-tree &>/dev/null; then
  LEAKED=$(git log --all -p 2>/dev/null | grep -cE '(sk-proj-|sk-ant-)[A-Za-z0-9]{20,}' || echo "0")
  if [ "$LEAKED" -gt 0 ]; then
    echo "  FAIL: $LEAKED potential API key(s) found in git history"
    echo "  ACTION: Rotate keys immediately and use git-filter-repo to purge"
  else
    echo "  PASS: No API keys found in git history"
  fi
fi

Step 3: Verify API Keys Not in Settings

Code Pack: Config
hth-cursor-3.01-api-key-env-setup.sh View source on GitHub ↗
# INSECURE: Never hardcode API keys in Cursor settings files
# This is an example of what to SEARCH FOR and REMOVE:
#   "cursor.openai.apiKey": "sk-proj-abc123..."
#   "cursor.anthropic.apiKey": "sk-ant-abc123..."
# Add API keys as environment variables in your shell profile
# For zsh (default on macOS):
cat >> ~/.zshrc <<'ENVVARS'

# Cursor AI Provider API Keys (rotate quarterly — see HTH 3.2)
export OPENAI_API_KEY="sk-proj-YOUR-KEY-HERE"
export ANTHROPIC_API_KEY="sk-ant-YOUR-KEY-HERE"
ENVVARS

source ~/.zshrc
echo "API keys added to ~/.zshrc as environment variables"
# Verify no hardcoded API keys exist in Cursor settings files
echo "=== Scanning for hardcoded API keys in Cursor settings ==="
SETTINGS_PATHS=(
  "${HOME}/Library/Application Support/Cursor/User/settings.json"
  "${HOME}/.config/Cursor/User/settings.json"
  ".vscode/settings.json"
)

FOUND=0
for f in "${SETTINGS_PATHS[@]}"; do
  if [ -f "$f" ]; then
    if grep -qE '(sk-proj-|sk-ant-|OPENAI_API_KEY|ANTHROPIC_API_KEY)' "$f" 2>/dev/null; then
      echo "  FAIL: Hardcoded key found in $f"
      FOUND=$((FOUND + 1))
    fi
  fi
done

if [ "$FOUND" -eq 0 ]; then
  echo "  PASS: No hardcoded API keys found in settings files"
fi

# Also check git history for accidentally committed keys
echo ""
echo "=== Checking git history for leaked keys ==="
if command -v git &>/dev/null && git rev-parse --is-inside-work-tree &>/dev/null; then
  LEAKED=$(git log --all -p 2>/dev/null | grep -cE '(sk-proj-|sk-ant-)[A-Za-z0-9]{20,}' || echo "0")
  if [ "$LEAKED" -gt 0 ]; then
    echo "  FAIL: $LEAKED potential API key(s) found in git history"
    echo "  ACTION: Rotate keys immediately and use git-filter-repo to purge"
  else
    echo "  PASS: No API keys found in git history"
  fi
fi

Time to Complete: ~10 minutes

Monitoring & Maintenance

  • Monthly: Rotate API keys
  • Quarterly: Audit environment variable security

Compliance Mappings

Framework Control ID Control Description
SOC 2 CC6.1 Secret management
NIST 800-53 IA-5(1) Password-based authentication
PCI DSS 8.2.1 Render credentials unreadable

3.2 Rotate AI Provider API Keys Quarterly

Profile Level: L2 (Walk) NIST 800-53: IA-5(1)

Description

Establish a quarterly rotation schedule for all AI provider API keys used with Cursor.

Rationale

Why This Matters:

  • Limits exposure window if keys compromised
  • Follows secret management best practices
  • Required by many compliance frameworks
  • A leaked provider key is billable as well as confidential — an unrotated key funds an attacker’s inference until someone notices the invoice (see 3.3)

Attack Prevented: Indefinite reuse of a leaked or exfiltrated provider API key, and persistent unauthorized inference access after a developer offboards or a workstation is compromised

ClickOps Implementation

Step 1: Create API Key Rotation Schedule

  1. Document all API keys in use (OpenAI, Anthropic, Google, custom providers)
  2. Set quarterly rotation reminders

Step 2: Rotate Keys

For OpenAI:

  1. Visit: https://platform.openai.com/api-keys
  2. Click Create new secret key
  3. Update environment variable:
Code Pack: Config
hth-cursor-3.02-api-key-rotation.sh View source on GitHub ↗
# Update environment variable with new key after generating on provider dashboard
# For zsh:
sed -i '' 's|^export OPENAI_API_KEY=.*|export OPENAI_API_KEY="sk-proj-NEW-KEY-HERE"|' ~/.zshrc
source ~/.zshrc
echo "OpenAI API key rotated in ~/.zshrc"

# For bash:
# sed -i 's|^export OPENAI_API_KEY=.*|export OPENAI_API_KEY="sk-proj-NEW-KEY-HERE"|' ~/.bashrc
# source ~/.bashrc
  1. Restart Cursor
  2. Verify new key works
  3. Revoke old key on OpenAI platform

For Anthropic:

  1. Visit: https://console.anthropic.com/settings/keys
  2. Generate new key → Update environment → Revoke old key

Time to Complete: ~15 minutes per provider


3.3 Monitor API Key Usage and Costs

Profile Level: L2 (Walk)

Description

Monitor AI provider API usage to detect anomalies (unusual spikes, unauthorized usage, cost overruns).

Rationale

Why This Matters:

  • A leaked or stolen AI provider key usually surfaces first as an abnormal spike in token usage or spend, well before any other indicator appears
  • Hard billing limits cap the financial blast radius of a compromised key, a runaway agent loop, or an abusive integration
  • Per-user usage review exposes shadow usage and insider misuse that account-level controls alone would miss
  • Cursor connects to multiple providers (OpenAI, Anthropic, Google, custom keys), so usage anomalies are the most practical signal of credential abuse across all of them

Attack Prevented: API key abuse, undetected credential theft, denial-of-wallet via cost exhaustion, runaway agent token consumption

ClickOps Implementation

Step 1: Enable Usage Tracking

For OpenAI:

  1. Visit: https://platform.openai.com/usage
  2. Set up billing alerts:
    • Soft limit: Warning at $X per month
    • Hard limit: Block at $Y per month

For Anthropic:

  1. Visit: https://console.anthropic.com/settings/billing
  2. Configure usage alerts

Step 2: Review Usage Regularly

  • Daily: Check for cost spikes
  • Weekly: Review usage patterns
  • Monthly: Analyze per-user usage (if using organization accounts)

4. MCP Server Security

4.1 Audit and Allowlist MCP Servers

Profile Level: L1 (Crawl) NIST 800-53: CM-7, SA-9

Description

Audit all configured MCP (Model Context Protocol) servers and restrict usage to an approved allowlist. MCP servers extend Cursor’s capabilities by connecting to external tools and services, but represent one of the most significant attack surfaces — three CVEs in 2025 directly exploited MCP configuration.

Rationale

Why This Matters:

  • MCP server installation (via pip install or npx) executes arbitrary code with full user permissions — no sandboxing by default
  • CVE-2025-54135 (CurXecute): Prompt injection via MCP-connected services (e.g., Slack) rewrote mcp.json and executed arbitrary commands
  • CVE-2025-54136 (MCPoison): After initial approval, attackers silently swapped benign MCP configs with malicious payloads for persistent RCE
  • CVE-2025-64106: Insufficient validation in MCP deep-link handling enabled malicious server impersonation
  • 53% of MCP servers rely on static API keys or PATs that are rarely rotated
  • 43% of tested MCP implementations had unsafe shell calls exposing them to command injection

Attack Prevented: Remote code execution via MCP prompt injection, persistent team-wide compromise, supply chain poisoning

Real-World Context:

  • Between January-February 2026, over 30 CVEs were filed targeting MCP servers, clients, and infrastructure
  • Among 2,614 MCP implementations surveyed, 82% use file operations vulnerable to path traversal

Prerequisites

  • Inventory of all MCP servers in use across the organization
  • Enterprise plan for centralized MCP allowlisting

ClickOps Implementation

Step 1: Audit Existing MCP Configurations

Code Pack: Config
hth-cursor-4.01-mcp-audit.sh View source on GitHub ↗
# Audit all MCP server configurations across project and global scopes
echo "=== MCP Configuration Audit ==="

# Project-level MCP config
PROJECT_MCP=".cursor/mcp.json"
if [ -f "$PROJECT_MCP" ]; then
  echo "Project MCP config found: $PROJECT_MCP"
  echo "  Configured servers:"
  jq -r '.mcpServers // {} | keys[]' "$PROJECT_MCP" 2>/dev/null || echo "  (invalid JSON)"
  echo ""
  echo "  Full config (review for suspicious commands/URLs):"
  cat "$PROJECT_MCP"
else
  echo "No project-level MCP config found (OK)"
fi

echo ""

# Global MCP config
GLOBAL_MCP="${HOME}/.cursor/mcp.json"
if [ -f "$GLOBAL_MCP" ]; then
  echo "Global MCP config found: $GLOBAL_MCP"
  echo "  Configured servers:"
  jq -r '.mcpServers // {} | keys[]' "$GLOBAL_MCP" 2>/dev/null || echo "  (invalid JSON)"
  echo ""
  echo "  Full config (review for suspicious commands/URLs):"
  cat "$GLOBAL_MCP"
else
  echo "No global MCP config found (OK if MCP not used)"
fi

echo ""
echo "=== Review Checklist ==="
echo "  [ ] Every MCP server is from a trusted source"
echo "  [ ] No unexpected 'command' entries with curl, wget, or shell pipes"
echo "  [ ] No servers pointing to unknown URLs or IP addresses"
echo "  [ ] Config files are not writable by other users (check permissions)"
# Lock down MCP config file permissions to prevent unauthorized modification
echo "=== Securing MCP config file permissions ==="
for MCP_FILE in ".cursor/mcp.json" "${HOME}/.cursor/mcp.json"; do
  if [ -f "$MCP_FILE" ]; then
    chmod 600 "$MCP_FILE"
    echo "  Set $MCP_FILE to 600 (owner read/write only)"
  fi
done

Step 2: Establish MCP Allowlist

  1. For Enterprise: Navigate to admin dashboard → MCP Servers → Configure allowlist
  2. Add only vetted, organizationally-approved MCP servers
  3. Block all other MCP server installations

Step 3: Secure MCP Config File Permissions

Code Pack: Config
hth-cursor-4.01-mcp-audit.sh View source on GitHub ↗
# Audit all MCP server configurations across project and global scopes
echo "=== MCP Configuration Audit ==="

# Project-level MCP config
PROJECT_MCP=".cursor/mcp.json"
if [ -f "$PROJECT_MCP" ]; then
  echo "Project MCP config found: $PROJECT_MCP"
  echo "  Configured servers:"
  jq -r '.mcpServers // {} | keys[]' "$PROJECT_MCP" 2>/dev/null || echo "  (invalid JSON)"
  echo ""
  echo "  Full config (review for suspicious commands/URLs):"
  cat "$PROJECT_MCP"
else
  echo "No project-level MCP config found (OK)"
fi

echo ""

# Global MCP config
GLOBAL_MCP="${HOME}/.cursor/mcp.json"
if [ -f "$GLOBAL_MCP" ]; then
  echo "Global MCP config found: $GLOBAL_MCP"
  echo "  Configured servers:"
  jq -r '.mcpServers // {} | keys[]' "$GLOBAL_MCP" 2>/dev/null || echo "  (invalid JSON)"
  echo ""
  echo "  Full config (review for suspicious commands/URLs):"
  cat "$GLOBAL_MCP"
else
  echo "No global MCP config found (OK if MCP not used)"
fi

echo ""
echo "=== Review Checklist ==="
echo "  [ ] Every MCP server is from a trusted source"
echo "  [ ] No unexpected 'command' entries with curl, wget, or shell pipes"
echo "  [ ] No servers pointing to unknown URLs or IP addresses"
echo "  [ ] Config files are not writable by other users (check permissions)"
# Lock down MCP config file permissions to prevent unauthorized modification
echo "=== Securing MCP config file permissions ==="
for MCP_FILE in ".cursor/mcp.json" "${HOME}/.cursor/mcp.json"; do
  if [ -f "$MCP_FILE" ]; then
    chmod 600 "$MCP_FILE"
    echo "  Set $MCP_FILE to 600 (owner read/write only)"
  fi
done

Step 4: Monitor MCP Configuration Changes

  1. Set up file integrity monitoring on .cursor/mcp.json (project and global)
  2. Alert on any modification to MCP configuration files
  3. Require re-approval for any MCP configuration change (enforced in Cursor 1.3+)

Time to Complete: ~30 minutes

Validation & Testing

  1. Verify only approved MCP servers are configured
  2. Attempt to add an unapproved MCP server — should be blocked (Enterprise)
  3. Modify an approved MCP config — should trigger re-approval prompt

Expected result: Only vetted MCP servers active, all changes require explicit approval

Operational Impact

Aspect Impact Level Details
Developer Workflow Medium Must request approval for new MCP servers
Security Posture Critical Improvement Prevents the most exploited attack vector in 2025
Maintenance Burden Medium Ongoing review of MCP server requests
Rollback Difficulty Easy Re-enable MCP servers as needed

Compliance Mappings

Framework Control ID Control Description
NIST 800-53 CM-7 Least functionality
NIST 800-53 SA-9 External system services
OWASP LLM LLM03 Supply chain vulnerabilities
OWASP Agentic ASI05 Supply chain risks
MITRE ATLAS AML.T0063 Publish poisoned AI agent tool

4.2 Enable MCP Tool Protection

Profile Level: L1 (Crawl) NIST 800-53: AC-6

Description

Enable MCP Tool Protection to require explicit user approval before any MCP tool executes. This prevents prompt injection from triggering MCP tool calls without user consent.

Rationale

Why This Matters:

  • Without tool protection, a prompt injection payload in a repository file or chat message can trigger MCP tools automatically
  • MCP tools can read files, execute commands, and make network requests with the developer’s full privileges
  • Tool Protection ensures human-in-the-loop for all MCP operations
  • Cursor’s documented model has two approval points, not one: the MCP connection itself requires approval, and thereafter “each tool call still needs individual approval before running” — an approved server is not an approved set of tools
  • The MCP allowlist exists to pre-approve specific tools. Every entry on it is a permanent removal of the second approval point for that tool, so the allowlist is the thing to audit, not the connection list

Attack Prevented: Prompt-injection-triggered MCP tool execution, silent invocation of file-read, shell, or network tools with developer privileges, and over-broad trust granted to a server on the basis of one connection approval

ClickOps Implementation

Step 1: Keep per-tool approval in force

  1. Open Cursor → SettingsFeaturesMCP
  2. Confirm that tool calls require approval. Cursor documents that all MCP connections require initial approval and that each tool call then needs individual approval before running
  3. Do not treat connection approval as sufficient — the per-call prompt is the control

Step 2: Audit the MCP allowlist

  1. Review every tool that has been pre-approved via the MCP allowlist
  2. Remove entries for tools that write files, execute commands, or make network requests — these are precisely the tools whose approval prompt matters
  3. Keep the allowlist to genuinely read-only, low-consequence tools, and re-review it on a schedule

Step 3: Also Enable Dotfile Protection

  1. In same settings area, enable Dotfile Protection
  2. This prevents AI from modifying sensitive files: .env, .ssh/config, .aws/credentials, etc.

Time to Complete: ~5 minutes

Compliance Mappings

Framework Control ID Control Description
NIST 800-53 AC-6 Least privilege
OWASP Agentic ASI02 Tool misuse
OWASP Agentic ASI03 Identity and privilege abuse

5. Agent & Sandbox Security

5.1 Disable Auto-Run Mode

Profile Level: L1 (Crawl) NIST 800-53: CM-7, AC-6

Description

Keep terminal commands behind explicit human approval — do not widen Cursor’s Run Modes to auto-run trusted commands (sometimes called “YOLO mode”). This is the single most impactful security control for Cursor.

Cursor’s current documented model is a set of approval tiers. Reading files and code search need no approval, and the agent may modify workspace files except configuration files. Approval is required for terminal commands, configuration-file changes, actions that expose sensitive data, and MCP connections and tool calls. Run Modes are the mechanism that relaxes the terminal-command tier, ranging from a simple allowlist through to an Auto-review classifier.

The vendor does not claim Run Modes are a security boundary. Cursor describes them as “best-effort guardrails rather than a hard security boundary.” Treat any relaxation of the terminal approval tier as a productivity trade you are making knowingly, not as a control you can attest to.

Rationale

Why This Matters:

  • In auto-run mode, Cursor’s agent executes terminal commands without any user approval
  • The command denylist uses a blocklist approach that has been repeatedly bypassed by researchers
  • The vendor’s own framing of Run Modes as best-effort means an auditor cannot be told that an allowlisted-command configuration prevents arbitrary execution — only that it discourages it
  • The default posture is already the secure one for terminal commands: approval is required unless someone widens it. The work here is preventing drift, not enabling a feature
  • CVE-2026-22708 (NomShub): Shell builtins (export, cd, eval) bypass the command allowlist entirely because the parser only tracks external executables — enabling “deterministic, 100% reliable sandbox escape”
  • GHSA-82wg-qcm4-fp2w: Environment variable manipulation bypassed the terminal allowlist
  • Disabling auto-run prevents the majority of documented attack scenarios

Attack Prevented: Autonomous code execution, sandbox escape via shell builtins, privilege escalation, data exfiltration

Real-World Context:

  • CyberScoop reported a one-line prompt attack that morphed Cursor’s agent into a local shell with full developer privileges
  • The NomShub attack chain achieved persistent remote access by chaining prompt injection → sandbox escape → ~/.zshenv overwrite → GitHub OAuth device code hijack

ClickOps Implementation

Step 1: Disable Auto-Run

  1. Open Cursor → Settings
  2. Search for: auto-run or autoRun
  3. Disable: Agent Auto-Run
Code Pack: Config
hth-cursor-5.01-agent-settings.sh View source on GitHub ↗
# Cursor settings to disable auto-run and enforce manual approval
# Add to .vscode/settings.json or user settings:
cat <<'SETTINGS'
{
  "cursor.agent.autoRun": false,
  "cursor.agent.enableSandbox": true,
  "cursor.agent.requireApprovalForCommands": true
}
SETTINGS
# Verify auto-run is disabled in all settings locations
echo "=== Checking Agent Auto-Run Status ==="
SETTINGS_PATHS=(
  "${HOME}/Library/Application Support/Cursor/User/settings.json"
  "${HOME}/.config/Cursor/User/settings.json"
  ".vscode/settings.json"
)

for f in "${SETTINGS_PATHS[@]}"; do
  if [ -f "$f" ]; then
    AUTORUN=$(grep -o '"cursor.agent.autoRun"[[:space:]]*:[[:space:]]*[a-z]*' "$f" 2>/dev/null || echo "not set")
    echo "  $f: $AUTORUN"
    if echo "$AUTORUN" | grep -q "true"; then
      echo "    WARN: Auto-run is ENABLED — this allows agent to execute commands without approval"
    fi
  fi
done

Step 2: Verify Auto-Run is Disabled

Code Pack: Config
hth-cursor-5.01-agent-settings.sh View source on GitHub ↗
# Cursor settings to disable auto-run and enforce manual approval
# Add to .vscode/settings.json or user settings:
cat <<'SETTINGS'
{
  "cursor.agent.autoRun": false,
  "cursor.agent.enableSandbox": true,
  "cursor.agent.requireApprovalForCommands": true
}
SETTINGS
# Verify auto-run is disabled in all settings locations
echo "=== Checking Agent Auto-Run Status ==="
SETTINGS_PATHS=(
  "${HOME}/Library/Application Support/Cursor/User/settings.json"
  "${HOME}/.config/Cursor/User/settings.json"
  ".vscode/settings.json"
)

for f in "${SETTINGS_PATHS[@]}"; do
  if [ -f "$f" ]; then
    AUTORUN=$(grep -o '"cursor.agent.autoRun"[[:space:]]*:[[:space:]]*[a-z]*' "$f" 2>/dev/null || echo "not set")
    echo "  $f: $AUTORUN"
    if echo "$AUTORUN" | grep -q "true"; then
      echo "    WARN: Auto-run is ENABLED — this allows agent to execute commands without approval"
    fi
  fi
done

Time to Complete: ~2 minutes

Validation & Testing

  1. Start an agent session
  2. Agent proposes a terminal command
  3. Verify the command requires explicit “Run” approval
  4. Verify destructive commands (rm, git push) show warning

Expected result: Every terminal command requires explicit user approval

Operational Impact

Aspect Impact Level Details
Developer Productivity Low-Medium Must click “Run” for each agent command
Security Posture Critical Improvement Prevents autonomous code execution attacks
Maintenance Burden None One-time setting
Rollback Difficulty Easy Re-enable auto-run in settings

Compliance Mappings

Framework Control ID Control Description
NIST 800-53 CM-7 Least functionality
NIST 800-53 AC-6 Least privilege
OWASP Agentic ASI06 Code execution
OWASP Agentic ASI03 Identity and privilege abuse
MITRE ATLAS AML.T0061 AI agent tools abuse

5.2 Constrain the Agent’s Approval and Network Posture

Profile Level: L2 (Walk) NIST 800-53: SC-39, CM-7, SC-7

Description

Keep the agent inside the approval tiers and default network posture Cursor documents, and resist the pressure to widen them. The current vendor-documented model is an approval framework rather than a configurable OS-level sandbox: certain actions run freely, certain actions require approval, and Run Modes relax the terminal tier at the cost of the guarantee.

Sources changed under this control (2026-08). Earlier revisions of this guide described sandbox internals — Apple Seatbelt scope on macOS, Landlock plus seccomp on Linux, the Linux sandbox running inside WSL2 on Windows — along with a Settings → Agent → Security → Sandbox Mode path and three Cursor 2.5+ network modes driven by sandbox.json. Both sandbox documentation URLs now return 404, and the live agent-security documentation describes the approval framework below instead. Those specifics are recorded here as previously documented; not present in current public docs (2026-08) and are not asserted. Verify the sandbox settings available in your installed Cursor version directly before relying on them.

Rationale

Why This Matters:

  • The agent’s default posture is the hardened one: Cursor documents that “agents cannot make arbitrary network requests with default settings,” with access limited to GitHub, direct link retrieval, and web search providers. Most real-world weakening comes from someone relaxing this, not from the default
  • Approval tiers are asymmetric by design — reading and searching are free, but terminal commands, configuration-file changes, and actions exposing sensitive data are gated. Configuration files are specifically excluded from free-edit, which is what stops an agent quietly rewriting the settings that constrain it
  • Run Modes are the release valve on the terminal tier, and Cursor calls them “best-effort guardrails rather than a hard security boundary” — so the isolation story cannot rest on them
  • Local agents retain broad filesystem read access, including paths such as ~/.ssh/, ~/.aws/, and .env files, so read-side exposure is governed by .cursorignore (2.3) and secret hygiene (7.2), not by the agent’s approval tiers
  • Researchers have demonstrated escapes via shell builtins (NomShub) and via macOS sandbox scope, so defence has to be layered across approval (5.1), hooks (11.3), and network allowlisting (9.2)

Attack Prevented: Agent-initiated network egress to attacker-controlled endpoints, agent modification of the configuration files that define its own constraints, and privilege expansion through progressively widened Run Modes

ClickOps Implementation

Step 1: Confirm the default network posture is intact

  1. Verify agents are not permitted arbitrary outbound network access — Cursor’s documented default limits requests to GitHub, direct link retrieval, and web search providers
  2. If someone has widened this for a workflow, record who, why, and for which teams. Undocumented widening is the finding
  3. Layer the endpoint allowlist from 9.2 underneath, so network policy holds even if the in-product setting changes

Step 2: Preserve the configuration-file approval tier

  1. Confirm the agent still requires approval to modify configuration files — this is the tier that protects .cursor/ rules (6.1), hooks configuration (11.3), and .cursorignore (2.3) from agent self-modification
  2. Treat any change that lets the agent edit configuration files without approval as a critical regression

Step 3: Keep Run Modes narrow

  1. Prefer the strictest available mode; a broad allowlist and the Auto-review classifier both sit on the vendor’s “best-effort” caveat
  2. Where a team needs a wider mode, scope it to that team rather than the organization, and pair it with blocking hooks (11.3), which are the enforceable layer

Step 4: Verify against your installed version

  1. Open your installed Cursor build and record which agent security and sandbox settings actually exist in it
  2. Where a setting this guide previously described is absent, do not assume it is applied silently — capture the gap and compensate with 9.2 and 11.3

Time to Complete: ~10 minutes

Validation & Testing

  1. Ask an agent to fetch a URL outside the permitted set and confirm it cannot
  2. Ask an agent to modify a configuration file and confirm an approval prompt appears
  3. Confirm the Run Mode in effect for each team matches what you documented
  4. Confirm blocking hooks (11.3) deny a representative dangerous command, since that is the layer that does not carry a best-effort caveat

Compliance Mappings

Framework Control ID Control Description
NIST 800-53 SC-39 Process isolation
NIST 800-53 CM-7 Least functionality
NIST 800-53 SC-7 Boundary protection
OWASP Agentic ASI06 Code execution controls

5.3 Secure Background/Cloud Agents

Profile Level: L3 (Run) NIST 800-53: SC-7, AC-6

Description

Configure security controls for Cursor’s Background Agents (remote cloud agents that run in isolated Ubuntu VMs on Cursor’s AWS infrastructure) or deploy self-hosted cloud agents for maximum control.

Rationale

Why This Matters:

  • Background agents clone repositories, work on branches, and submit PRs autonomously
  • Cursor acknowledges background agents have “a much bigger surface area of attacks compared to existing Cursor features”
  • Cloud agents with Computer Use (Feb 2026) gave each agent its own VM with browser access and video recording — creating lateral movement risk if compromised
  • Self-hosted cloud agents (March 2026) keep code and execution entirely within your infrastructure

Attack Prevented: Code exfiltration via cloud agents, lateral movement from compromised agent VMs

ClickOps Implementation

Option A: Restrict Cloud Agent Usage

  1. For Enterprise: In admin dashboard, disable Cloud Agents entirely
  2. Or configure agent run settings to require approval for all cloud agent operations

Option B: Deploy Self-Hosted Cloud Agents (Enterprise)

  1. Self-hosted agents run entirely within your infrastructure using outbound-only HTTPS connections
  2. Deploy via Helm chart or Kubernetes operator
  3. Code, tool execution, and build artifacts never leave your environment
  4. No inbound ports, firewall changes, or VPNs needed

Time to Complete: ~2 hours (self-hosted) or ~5 minutes (restrict)

Compliance Mappings

Framework Control ID Control Description
NIST 800-53 SC-7 Boundary protection
NIST 800-53 AC-6 Least privilege
NIST AI RMF MANAGE 1.3 AI deployment risk management

6. Rules File & Project Security

6.1 Audit .cursorrules for Hidden Payloads

Profile Level: L1 (Crawl) NIST 800-53: SI-3, CM-7

Description

Scan .cursorrules and .cursor/rules/*.mdc files for hidden Unicode characters and suspicious instructions that could carry prompt injection payloads. Rules files define project-level AI instructions that automatically apply to all AI interactions — making them a potent supply chain attack vector.

Rationale

Why This Matters:

  • Pillar Security demonstrated that invisible Unicode characters (zero-width joiners, bidirectional text markers) embedded in .cursorrules files silently instruct the AI to inject backdoors into all generated code
  • Instructions are invisible in code editors and GitHub diffs
  • Compromised rules files affect all team members who clone the repository
  • Attack survives project forking — creating downstream supply chain contamination
  • No trace in chat history or coding logs; security teams have zero visibility
  • Cursor disputed this as “not a vulnerability on their side”

Attack Prevented: Supply chain poisoning via rules file prompt injection, invisible backdoor insertion, team-wide code compromise

Real-World Context:

  • GitHub added hidden Unicode warnings to diffs by May 2025, implicitly validating the risk
  • HiddenLayer researchers demonstrated control token abuse (<user_query>, <user_info>) to escalate malicious instructions to user-instruction privilege level

ClickOps Implementation

Step 1: Scan Rules Files for Hidden Unicode

Code Pack: Config
hth-cursor-6.01-rules-file-audit.sh View source on GitHub ↗
# Scan .cursorrules and .cursor/rules/ for hidden Unicode characters
# that could carry invisible prompt injection payloads
echo "=== Scanning for hidden Unicode in AI rules files ==="

RULES_FILES=()
[ -f ".cursorrules" ] && RULES_FILES+=(".cursorrules")
if [ -d ".cursor/rules" ]; then
  while IFS= read -r -d '' f; do
    RULES_FILES+=("$f")
  done < <(find .cursor/rules -type f -name "*.mdc" -print0 2>/dev/null)
fi

if [ ${#RULES_FILES[@]} -eq 0 ]; then
  echo "  No rules files found in project (OK)"
  exit 0
fi

FOUND_HIDDEN=0
for f in "${RULES_FILES[@]}"; do
  # Detect zero-width characters, bidirectional markers, and other invisible Unicode
  # U+200B (zero-width space), U+200C/D (zero-width non-joiner/joiner),
  # U+200E/F (LTR/RTL marks), U+2060 (word joiner), U+FEFF (BOM)
  HIDDEN=$(grep -cP '[\x{200B}-\x{200F}\x{2028}-\x{202F}\x{2060}\x{FEFF}]' "$f" 2>/dev/null || echo "0")
  if [ "$HIDDEN" -gt 0 ]; then
    echo "  FAIL: $f contains $HIDDEN line(s) with hidden Unicode characters"
    echo "    View with: cat -v '$f' | grep -n 'M-b'"
    FOUND_HIDDEN=$((FOUND_HIDDEN + 1))
  else
    echo "  PASS: $f — no hidden Unicode detected"
  fi
done

if [ "$FOUND_HIDDEN" -gt 0 ]; then
  echo ""
  echo "ACTION: Review flagged files with a hex editor before trusting"
  echo "  hexdump -C <file> | grep -E '(e2 80 8[b-f]|e2 80 a[a-f]|ef bb bf)'"
fi
# Review rules files for suspicious instructions
echo "=== Content Review of AI Rules Files ==="

SUSPICIOUS_PATTERNS=(
  'curl\s'
  'wget\s'
  'eval\s'
  'exec\('
  'system\('
  'subprocess'
  'base64'
  'reverse.shell'
  '/dev/tcp'
  'nc\s.*-e'
  '<user_query>'
  '<user_info>'
  'ignore.*previous.*instructions'
  'disregard.*above'
)

PATTERN=$(printf '%s|' "${SUSPICIOUS_PATTERNS[@]}")
PATTERN=${PATTERN%|}

for f in "${RULES_FILES[@]}"; do
  MATCHES=$(grep -ciE "$PATTERN" "$f" 2>/dev/null || echo "0")
  if [ "$MATCHES" -gt 0 ]; then
    echo "  WARN: $f has $MATCHES suspicious pattern(s):"
    grep -niE "$PATTERN" "$f" 2>/dev/null | head -5
  else
    echo "  PASS: $f — no suspicious patterns"
  fi
done

Step 2: Review Rules File Content for Suspicious Patterns

Code Pack: Config
hth-cursor-6.01-rules-file-audit.sh View source on GitHub ↗
# Scan .cursorrules and .cursor/rules/ for hidden Unicode characters
# that could carry invisible prompt injection payloads
echo "=== Scanning for hidden Unicode in AI rules files ==="

RULES_FILES=()
[ -f ".cursorrules" ] && RULES_FILES+=(".cursorrules")
if [ -d ".cursor/rules" ]; then
  while IFS= read -r -d '' f; do
    RULES_FILES+=("$f")
  done < <(find .cursor/rules -type f -name "*.mdc" -print0 2>/dev/null)
fi

if [ ${#RULES_FILES[@]} -eq 0 ]; then
  echo "  No rules files found in project (OK)"
  exit 0
fi

FOUND_HIDDEN=0
for f in "${RULES_FILES[@]}"; do
  # Detect zero-width characters, bidirectional markers, and other invisible Unicode
  # U+200B (zero-width space), U+200C/D (zero-width non-joiner/joiner),
  # U+200E/F (LTR/RTL marks), U+2060 (word joiner), U+FEFF (BOM)
  HIDDEN=$(grep -cP '[\x{200B}-\x{200F}\x{2028}-\x{202F}\x{2060}\x{FEFF}]' "$f" 2>/dev/null || echo "0")
  if [ "$HIDDEN" -gt 0 ]; then
    echo "  FAIL: $f contains $HIDDEN line(s) with hidden Unicode characters"
    echo "    View with: cat -v '$f' | grep -n 'M-b'"
    FOUND_HIDDEN=$((FOUND_HIDDEN + 1))
  else
    echo "  PASS: $f — no hidden Unicode detected"
  fi
done

if [ "$FOUND_HIDDEN" -gt 0 ]; then
  echo ""
  echo "ACTION: Review flagged files with a hex editor before trusting"
  echo "  hexdump -C <file> | grep -E '(e2 80 8[b-f]|e2 80 a[a-f]|ef bb bf)'"
fi
# Review rules files for suspicious instructions
echo "=== Content Review of AI Rules Files ==="

SUSPICIOUS_PATTERNS=(
  'curl\s'
  'wget\s'
  'eval\s'
  'exec\('
  'system\('
  'subprocess'
  'base64'
  'reverse.shell'
  '/dev/tcp'
  'nc\s.*-e'
  '<user_query>'
  '<user_info>'
  'ignore.*previous.*instructions'
  'disregard.*above'
)

PATTERN=$(printf '%s|' "${SUSPICIOUS_PATTERNS[@]}")
PATTERN=${PATTERN%|}

for f in "${RULES_FILES[@]}"; do
  MATCHES=$(grep -ciE "$PATTERN" "$f" 2>/dev/null || echo "0")
  if [ "$MATCHES" -gt 0 ]; then
    echo "  WARN: $f has $MATCHES suspicious pattern(s):"
    grep -niE "$PATTERN" "$f" 2>/dev/null | head -5
  else
    echo "  PASS: $f — no suspicious patterns"
  fi
done

Step 3: Establish Rules File Governance

  1. Treat .cursor/ directory and .cursorrules files as security-critical in code review — equivalent to CI/CD pipeline configurations
  2. Require explicit review of all changes to rules files in pull requests
  3. Maintain an approved rules file template for your organization (see CSA R.A.I.L.G.U.A.R.D. framework)

Time to Complete: ~15 minutes per repository

Validation & Testing

  1. Create a test rules file with a hidden Unicode character
  2. Run the scanning script — should detect and flag it
  3. Review flagged file with hex editor to confirm

Expected result: All rules files are free of hidden Unicode and suspicious patterns

Compliance Mappings

Framework Control ID Control Description
NIST 800-53 SI-3 Malicious code protection
NIST 800-53 CM-7 Least functionality
OWASP LLM LLM01 Prompt injection
OWASP Agentic ASI01 Agent goal hijacking
OWASP Agentic ASI04 Memory poisoning
MITRE ATLAS AML.T0051 LLM prompt injection

6.2 Enforce Rules File Review in PRs

Profile Level: L2 (Walk) NIST 800-53: CM-3

Description

Require mandatory code review for any changes to AI rules files (.cursorrules, .cursor/rules/*.mdc) before they are merged. Implement CODEOWNERS rules to enforce security team review.

Rationale

Why This Matters:

  • Rules file changes affect all future AI interactions for the entire team
  • Malicious changes can be subtle (single-line instruction additions, Unicode injection)
  • Without mandatory review, a compromised contributor can silently weaponize AI output
  • Project-scoped hooks (.cursor/hooks.json, see 11.3) live in the same directory and carry more authority than rules — a hook can block, allow, or rewrite tool inputs — so the same review gate must cover them

Attack Prevented: Silent weaponization of team-wide AI behaviour through an unreviewed rules or hooks change, and prompt-injection payloads reaching main without a human ever reading the diff

ClickOps Implementation

Step 1: Add Rules Files to CODEOWNERS

  1. In your repository, add to .github/CODEOWNERS:
    • .cursorrules @security-team
    • .cursor/rules/ @security-team
    • .cursor/mcp.json @security-team
    • .cursor/hooks.json @security-team
    • .vscode/tasks.json @security-team
  2. Enable branch protection requiring CODEOWNERS approval

Step 2: Configure Pre-Commit Hook (Optional)

  1. Add a pre-commit hook that runs the Unicode scanning script from Control 6.1
  2. Block commits containing hidden Unicode in rules files

Time to Complete: ~15 minutes

Compliance Mappings

Framework Control ID Control Description
NIST 800-53 CM-3 Configuration change control
SOC 2 CC8.1 Changes are authorized
NIST SP 800-218A PW.7.1 Review code changes

7. Workspace Trust & Code Security

7.1 Enable Workspace Trust for All Repositories

Profile Level: L1 (Crawl) NIST 800-53: CM-7

Description

Enable VSCode/Cursor Workspace Trust to prevent automatic execution of untrusted code when opening new repositories. Cursor ships with Workspace Trust disabled by default — a deliberate design choice that creates a critical attack vector.

Rationale

Why This Matters:

  • With Workspace Trust disabled (Cursor’s default), a malicious .vscode/tasks.json with runOptions.runOn: "folderOpen" auto-executes arbitrary code the moment a developer opens a folder — no prompt, no consent, no AI involvement needed
  • Developer laptops typically hold cloud keys, PATs, API tokens, and SaaS sessions — a booby-trapped repo pivots immediately to CI/CD and cloud infrastructure
  • Cursor stated they “intended to keep the autorun behavior” because “Workspace Trust disables AI and other features our users want to use”
  • This vulnerability has no CVE assigned (it’s a design choice) but was disclosed by Oasis Security in September 2025

Attack Prevented: Arbitrary code execution from malicious repositories on folder open

Real-World Context:

  • Oasis Security demonstrated complete exploitation: clone repo → open in Cursor → immediate code execution with developer privileges

Prerequisites

  • Understanding of which repositories are trusted (internal, verified sources)
  • Communication to developers about trust prompts (they will see new prompts after enabling)

ClickOps Implementation

Step 1: Enable Workspace Trust

  1. Open Cursor → Settings
  2. Search for: security.workspace.trust.enabled — this is the exact setting identifier
  3. Apply the following settings:
Code Pack: Config
hth-cursor-7.01-workspace-trust-config.sh View source on GitHub ↗
# Cursor user settings to enable Workspace Trust (disabled by default in Cursor)
# Add to user settings.json:
cat <<'SETTINGS'
{
  "security.workspace.trust.enabled": true,
  "security.workspace.trust.startupPrompt": "always",
  "security.workspace.trust.emptyWindow": false,
  "security.workspace.trust.untrustedFiles": "prompt",
  "task.allowAutomaticTasks": "off"
}
SETTINGS
# Verify Workspace Trust is enabled (Cursor defaults it to OFF)
echo "=== Workspace Trust Verification ==="
SETTINGS_PATHS=(
  "${HOME}/Library/Application Support/Cursor/User/settings.json"
  "${HOME}/.config/Cursor/User/settings.json"
)

for f in "${SETTINGS_PATHS[@]}"; do
  if [ -f "$f" ]; then
    TRUST=$(grep -o '"security.workspace.trust.enabled"[[:space:]]*:[[:space:]]*[a-z]*' "$f" 2>/dev/null || echo "not set")
    TASKS=$(grep -o '"task.allowAutomaticTasks"[[:space:]]*:[[:space:]]*"[^"]*"' "$f" 2>/dev/null || echo "not set")
    echo "  $f:"
    echo "    Workspace Trust: $TRUST"
    echo "    Auto Tasks: $TASKS"

    if echo "$TRUST" | grep -q "false" || echo "$TRUST" | grep -q "not set"; then
      echo "    FAIL: Workspace Trust is disabled — repos with malicious .vscode/tasks.json can auto-execute code"
    fi
  fi
done

Step 1a: Enforce it centrally rather than per developer (Enterprise)

A per-machine setting a developer can turn off is a recommendation, not a control. Cursor exposes workspace trust as an MDM policy key — WorkspaceTrustEnabled, corresponding to the client setting security.workspace.trust.enabled. Push it through MDM (see 11.2) so the setting cannot be reverted locally. Advanced identity controls including SCIM and MDM policies are documented as available on Enterprise.

Step 2: Configure Trusted Folders

  1. Add trusted parent directories:
    • Company code: ~/work/company-name/
    • Personal projects: ~/projects/personal/

Step 3: Verify Trust Prompts

  1. Clone a new repository outside trusted folders
  2. Open in Cursor
  3. Should see: “Do you trust the authors of the files in this folder?”
  4. Select “No, I don’t trust the authors” for untrusted repos

Step 4: Verify Workspace Trust is Active

Code Pack: Config
hth-cursor-7.01-workspace-trust-config.sh View source on GitHub ↗
# Cursor user settings to enable Workspace Trust (disabled by default in Cursor)
# Add to user settings.json:
cat <<'SETTINGS'
{
  "security.workspace.trust.enabled": true,
  "security.workspace.trust.startupPrompt": "always",
  "security.workspace.trust.emptyWindow": false,
  "security.workspace.trust.untrustedFiles": "prompt",
  "task.allowAutomaticTasks": "off"
}
SETTINGS
# Verify Workspace Trust is enabled (Cursor defaults it to OFF)
echo "=== Workspace Trust Verification ==="
SETTINGS_PATHS=(
  "${HOME}/Library/Application Support/Cursor/User/settings.json"
  "${HOME}/.config/Cursor/User/settings.json"
)

for f in "${SETTINGS_PATHS[@]}"; do
  if [ -f "$f" ]; then
    TRUST=$(grep -o '"security.workspace.trust.enabled"[[:space:]]*:[[:space:]]*[a-z]*' "$f" 2>/dev/null || echo "not set")
    TASKS=$(grep -o '"task.allowAutomaticTasks"[[:space:]]*:[[:space:]]*"[^"]*"' "$f" 2>/dev/null || echo "not set")
    echo "  $f:"
    echo "    Workspace Trust: $TRUST"
    echo "    Auto Tasks: $TASKS"

    if echo "$TRUST" | grep -q "false" || echo "$TRUST" | grep -q "not set"; then
      echo "    FAIL: Workspace Trust is disabled — repos with malicious .vscode/tasks.json can auto-execute code"
    fi
  fi
done

Time to Complete: ~5 minutes

What Gets Restricted in Untrusted Workspaces

Feature Trusted Untrusted
Tasks Run automatically Blocked
Debugging Enabled Disabled
Extensions Full functionality Limited/disabled
Settings (workspace) Applied Ignored
AI Features Full May be limited

Operational Impact

Aspect Impact Level Details
Developer Workflow Medium Must trust repos to use full features; prompts on first open
Security Posture Critical Improvement Prevents auto-execution from malicious repos
Maintenance Burden Low One-time trust decision per workspace

Compliance Mappings

Framework Control ID Control Description
NIST 800-53 CM-7 Least functionality
SOC 2 CC6.6 Logical access — malware protection
OWASP Agentic ASI01 Agent goal hijacking

7.2 Scan for Secrets in Code Before AI Processing

Profile Level: L2 (Walk) NIST 800-53: IA-5

Description

Use secret scanning tools to detect and remove secrets from code before allowing AI processing. Prevents accidental credential leakage to AI providers.

Rationale

Why This Matters:

  • Cursor sends code snippets to AI providers (unless Privacy Mode enabled)
  • Secrets in code sent to AI may be logged or retained by provider
  • AI chat history may contain secrets if discussing code with credentials
  • Researchers demonstrated that prompt injection can instruct Cursor to use grep to find API keys and exfiltrate them via curl

Attack Prevented: Credential leakage via AI context, secret exfiltration via prompt injection

ClickOps Implementation

Step 1: Install Secret Scanning Extension

  1. In Cursor, open Extensions (Cmd/Ctrl + Shift + X)
  2. Install: GitGuardian or TruffleHog extension
  3. Configure to scan on save

Step 2: Enable Pre-Commit Hooks

  1. Install pre-commit framework
  2. Add secret scanning hooks (e.g., detect-secrets, gitleaks, trufflehog)
  3. Run pre-commit install in repository

Step 3: Verify Secret Scanning

  1. Create test file with fake secret
  2. Attempt commit — should be blocked
  3. Remove secret and retry

8. Extension & Integration Security

8.1 Audit and Restrict VSCode Extensions

Profile Level: L1 (Crawl) NIST 800-53: CM-7

Description

Review all installed VSCode extensions and remove unnecessary or untrusted ones. Extensions have broad permissions and can access code, secrets, and network. Cursor uses the Open VSX registry instead of Microsoft’s official Marketplace — introducing unique supply chain risks.

Rationale

Why This Matters:

  • VSCode extensions can read all workspace files and make network requests
  • Cursor uses Open VSX, which has weaker verification than Microsoft’s Marketplace
  • In June 2025, a fake “Solidity Language” extension on Open VSX led to a confirmed $500,000 cryptocurrency theft — the extension was a dropper that installed remote access tools and credential stealers
  • In December 2025, researchers found Cursor was recommending extensions that didn’t exist in Open VSX, enabling attackers to register those names and publish malware that the IDE actively recommended

Attack Prevented: Malicious extension data exfiltration, cryptomining, credential theft, supply chain compromise

Real-World Context:

  • $500K crypto theft via malicious Open VSX extension (Kaspersky, July 2025)
  • Extension name squatting across Cursor, Windsurf, and Google Antigravity (December 2025)

ClickOps Implementation

Step 1: Audit Installed Extensions

Code Pack: Config
hth-cursor-8.01-extension-audit.sh View source on GitHub ↗
# List all installed extensions with install counts and publisher info
echo "=== Installed Extension Audit ==="
if command -v cursor &>/dev/null; then
  cursor --list-extensions --show-versions 2>/dev/null | while IFS= read -r ext; do
    echo "  $ext"
  done
  echo ""
  TOTAL=$(cursor --list-extensions 2>/dev/null | wc -l | tr -d ' ')
  echo "Total extensions: $TOTAL"
else
  echo "Cursor CLI not found in PATH"
  echo "Check: /Applications/Cursor.app/Contents/MacOS/Cursor --list-extensions"
fi

echo ""
echo "=== Extension Risk Checklist ==="
echo "  [ ] Remove extensions not updated in >1 year"
echo "  [ ] Remove extensions with <10K installs (less vetted)"
echo "  [ ] Verify publisher identity for all security-relevant extensions"
echo "  [ ] Check that no extensions were side-loaded from .vsix files"
echo "  [ ] Confirm extensions come from Open VSX with verified publishers"

Step 2: Remove Unnecessary Extensions

  1. Click extension → Uninstall
  2. Focus on:
    • Extensions with <10K installs (less vetted)
    • Extensions not updated in >1 year
    • Extensions requesting network/filesystem permissions unnecessarily
    • Extensions side-loaded from .vsix files

Step 3: Use Extension Allowlist (Enterprise)

Cursor exposes extension allowlisting two ways, and the interaction matters:

  1. Dashboard: configure the allowlist under Security & Identity in the admin dashboard. This corresponds to the client setting extensions.allowed
  2. MDM: the policy key is AllowedExtensions, and it overrides the dashboard configuration. If you deploy both, MDM wins — do not assume the dashboard list is in force on MDM-managed machines
  3. Version floor: dashboard-configured extension restrictions require Cursor client version 2.1 or later. Cursor states that “users on older versions will not have extension restrictions applied,” so pair the allowlist with a minimum-version requirement (10.1) or the control simply does not apply to part of your fleet
  4. Deploy via MDM (macOS) or Group Policy/Intune (Windows)
  5. Third-party plugin imports default to OFF on Enterprise (require explicit admin override)
Extension Category Risk Level Recommendation
Official Microsoft Low Generally safe
GitHub Official Low Safe
Popular (>1M installs, verified publisher) Low-Medium Review permissions
Niche (<10K installs) Medium-High Audit code before use
Side-loaded .vsix High Avoid; verify publisher and integrity
Deprecated/Unmaintained High Remove immediately

Compliance Mappings

Framework Control ID Control Description
NIST 800-53 CM-7 Least functionality
OWASP LLM LLM03 Supply chain vulnerabilities

9. Network & Telemetry Controls

9.1 Disable Telemetry and Crash Reporting

Profile Level: L2 (Walk) NIST 800-53: SC-4

Description

Disable telemetry data collection and crash reporting to prevent code snippets or metadata from being sent to Cursor/Microsoft.

Rationale

Why This Matters:

  • Telemetry may include code snippets, file paths, or project metadata
  • Crash reports can contain sensitive information
  • Reduces data exposure to third parties
  • Telemetry is a data flow that sits outside Privacy Mode’s retention guarantees and outside your data-residency scope (2.1), so it has to be disabled explicitly rather than assumed covered

Attack Prevented: Inadvertent disclosure of proprietary file paths, project structure, and code fragments through diagnostic channels that bypass the retention and residency controls applied to model traffic

ClickOps Implementation

Step 1: Disable All Telemetry

  1. Open Cursor → Settings
  2. Search for telemetry
  3. Apply the telemetry-disabling settings:
Code Pack: Config
hth-cursor-9.01-telemetry-config.sh View source on GitHub ↗
# Cursor/VSCode settings to disable all telemetry and data collection
# Add to user settings.json:
cat <<'SETTINGS'
{
  "telemetry.telemetryLevel": "off",
  "telemetry.enableCrashReporter": false,
  "telemetry.enableTelemetry": false,
  "cursor.general.enableShadowWorkspace": false,
  "cursor.general.allowAnonymousUsage": false
}
SETTINGS

Step 2: Verify Telemetry Disabled

  1. Check network traffic — should not see telemetry endpoints
  2. Use tools like Little Snitch (macOS) or Wireshark to monitor

9.2 Configure Network Allowlisting

Profile Level: L3 (Run) NIST 800-53: SC-7

Description

Use enterprise firewall or endpoint security to allowlist only required Cursor network endpoints, blocking all other traffic.

Rationale

Why This Matters:

  • Restricting Cursor to a known set of endpoints forces all AI model traffic through Cursor’s Privacy Mode proxy instead of direct provider APIs that bypass data-retention guarantees
  • An egress allowlist removes the exfiltration channels that prompt injection, a malicious extension, or a poisoned MCP server would use to reach attacker-controlled servers
  • Outbound filtering contains compromised agents and subprocesses that attempt to call out to unapproved hosts for command-and-control or data theft
  • Codebase context, embeddings, and credentials only leave the machine through network connections, so the network boundary is the last enforceable control when in-editor protections fail

Attack Prevented: Data exfiltration to unauthorized endpoints, Privacy Mode proxy bypass, command-and-control callbacks from compromised agents or extensions

Required Endpoints

The following are the hosts Cursor documents for enterprise network configuration. A previous revision of this guide listed *.cursor.com and marketplace.visualstudio.com; neither appears in Cursor’s documented endpoint list and both have been removed. *.cursorvm.com — the cloud-agent VM domain — was absent from the previous list and is required if Cloud Agents are in use.

Endpoint Purpose Required For
api2.cursor.sh, api3.cursor.sh, api4.cursor.sh, api5.cursor.sh Core API requests All users
us-asia.gcpp.cursor.sh, us-eu.gcpp.cursor.sh, us-only.gcpp.cursor.sh Region-specific request routing All users (varies by region/residency)
agent.api5.cursor.sh, agentn.api5.cursor.sh, agent.us.api5.cursor.sh, agentn.us.api5.cursor.sh, agent.global.api5.cursor.sh, agentn.global.api5.cursor.sh Agent network access layer Agent features
repo42.cursor.sh Repository indexing / embeddings Codebase indexing
authenticate.cursor.sh, authenticator.cursor.sh, authentication.cursor.sh, prod.authentication.cursor.sh Authentication and SSO All users
adminportal42.cursor.sh Admin portal Admins
marketplace.cursorapi.com Extension marketplace Extension management
cursor-cdn.com CDN for static assets All users
downloads.cursor.com Client downloads and updates All users
anysphere-binaries.s3.us-east-1.amazonaws.com Binary updates All users
*.cursorvm.com, *.*.cursorvm.com Cloud Agent VMs Cloud Agents (5.3)

Recommended wildcards. Where per-host allowlisting is impractical, Cursor documents these wildcards: *.cursor.sh, *.cursor-cdn.com, *.cursorapi.com, *.cursorvm.com, and *.*.cursorvm.com. Prefer the explicit host list at L3 — the wildcards trade precision for maintainability, and *.cursor.sh in particular admits every future subdomain without review.

Block all other network traffic from Cursor. If Cloud Agents are disabled per 5.3, omit the *.cursorvm.com entries rather than allowing them “just in case” — an unused allowlist entry is an available egress path.

Network Verification

Code Pack: Config
hth-cursor-9.02-network-allowlist.sh View source on GitHub ↗
# Monitor Cursor network connections and verify only approved endpoints
echo "=== Active Cursor Network Connections ==="
if [[ "$OSTYPE" == "darwin"* ]]; then
  lsof -i -n -P 2>/dev/null | grep -i cursor | grep ESTABLISHED
elif [[ "$OSTYPE" == "linux"* ]]; then
  ss -tnp 2>/dev/null | grep cursor
fi

echo ""
echo "=== Verify against approved endpoints ==="
echo "Required domains (allowlist these in firewall):"
echo "  *.cursor.com          — Core application services"
echo "  *.cursor.sh           — Authentication and SSO"
echo "  *.cursorapi.com       — API services and marketplace"
echo "  cursor-cdn.com        — CDN for static assets"
echo "  downloads.cursor.com  — Client downloads and updates"
echo ""
echo "Optional (only if using cloud AI providers):"
echo "  api.openai.com        — OpenAI API (routed through Cursor proxy)"
echo "  api.anthropic.com     — Anthropic API (routed through Cursor proxy)"
echo ""
echo "Block all other outbound connections from Cursor."

Important: All AI model requests route through Cursor’s infrastructure (the domains above), not directly to api.openai.com or api.anthropic.com. Blocking direct access to AI provider APIs forces traffic through Cursor’s Privacy Mode proxy.


10. Monitoring & Audit Logging

10.1 Enable Cursor Usage Logging

Profile Level: L2 (Walk) NIST 800-53: AU-2

Description

Configure logging of Cursor AI usage for audit and compliance purposes. Ensure Cursor is running a patched version to benefit from all security fixes.

Rationale

Why This Matters:

  • Compliance frameworks require logging of AI usage
  • Detect anomalous usage patterns (insider threats)
  • Attribution of AI-generated code
  • Version tracking prevents use of vulnerable Cursor releases — and several controls in this guide have hard version floors (extension allowlisting requires client 2.1+, see 8.1), so an unpatched fleet is also an unprotected one

Attack Prevented: Undetected insider misuse or account compromise, unattributable AI-generated code entering the codebase, and silent non-application of version-gated controls across an unpatched fleet

Verification note (2026-08): Cursor’s audit-log documentation URL returned 404 during this currency pass, so the event list, streaming destinations, and the “agent responses and generated code are not captured” claim below could not be re-verified against current vendor documentation. They are retained as previously documented. Confirm the actual event coverage and destination list in your Enterprise dashboard before relying on any of them for a control attestation — particularly the not-captured claim, which is a negative assertion and the costliest to be wrong about.

ClickOps Implementation

Step 1: Verify Cursor Version

Code Pack: Config
hth-cursor-10.01-cursor-version-check.sh View source on GitHub ↗
# Verify Cursor is running a patched version (minimum 1.7+ for 2025 CVE fixes)
echo "=== Cursor Version Check ==="
CURSOR_VERSION=""
if command -v cursor &>/dev/null; then
  CURSOR_VERSION=$(cursor --version 2>/dev/null | head -1)
elif [ -f "/Applications/Cursor.app/Contents/Resources/app/package.json" ]; then
  CURSOR_VERSION=$(grep '"version"' "/Applications/Cursor.app/Contents/Resources/app/package.json" 2>/dev/null | head -1)
fi

if [ -n "$CURSOR_VERSION" ]; then
  echo "  Installed version: $CURSOR_VERSION"
  echo ""
  echo "  Minimum safe versions:"
  echo "    >= 1.3   Patches CVE-2025-54135 (CurXecute) and CVE-2025-54136 (MCPoison)"
  echo "    >= 1.7   Patches CVE-2025-59944, CVE-2025-61590 through CVE-2025-61593"
  echo "    >= 2.0   Adds agent sandbox (macOS), improved MCP approval"
  echo "    >= 2.5   Adds sandbox network access controls"
else
  echo "  Unable to determine Cursor version"
fi

Step 2: Enable Built-in Logging (Enterprise)

  1. In admin dashboard, navigate to Compliance and Monitoring
  2. Enable audit logging — tracks:
    • Authentication events (logins, logouts)
    • User management (additions, removals, role changes)
    • API key management (creation, revocation)
    • Team settings changes
    • Privacy Mode changes
    • MCP server configuration changes
  3. Note: Agent responses and generated code content are NOT captured in audit logs

Step 3: Configure Log Streaming (Enterprise)

  1. Configure log forwarding to your SIEM platform
  2. Supported destinations: Splunk, Datadog, Sumo Logic, webhook endpoints, S3 buckets, Elasticsearch, CloudWatch
  3. Logs are JSON format with timestamps, event IDs, user details, IP addresses

10.2 Monitor for Suspicious Agent Activity

Profile Level: L2 (Walk) NIST 800-53: AU-6, SI-4

Description

Monitor developer workstations for indicators of Cursor-based attacks including unexpected process spawning, shell startup file modifications, and suspicious network connections.

Rationale

Why This Matters:

  • The NomShub attack chain persisted via ~/.zshenv overwrite
  • Prompt injection can spawn curl to exfiltrate data via agent terminal access
  • Unexpected cursor-tunnel processes may indicate remote access exploitation
  • Cursor’s own audit logs do not capture agent execution on the endpoint, so workstation telemetry is the only place these indicators appear at all

Attack Prevented: Persistence via shell startup file modification, data exfiltration through agent-spawned subprocesses, silent MCP configuration tampering, and remote access established through unexpected tunnel processes

ClickOps Implementation

Key Indicators to Monitor:

  1. Shell startup file modifications: Watch ~/.zshenv, ~/.bashrc, ~/.zprofile for unexpected changes
  2. Process tree anomalies: AI agents spawn child processes — EDR should monitor the full process tree from Cursor
  3. Unexpected network connections: Flag outbound connections from Cursor subprocesses to non-allowlisted endpoints
  4. MCP config changes: File integrity monitoring on .cursor/mcp.json (project and global)
  5. Cursor application file tampering: Monitor for modifications to Cursor’s main.js (malicious npm packages have overwritten this)
  6. cursor-tunnel processes: Monitor for unexpected remote tunnel activity

Compliance Mappings

Framework Control ID Control Description
NIST 800-53 AU-6 Audit record review
NIST 800-53 SI-4 System monitoring
OWASP Agentic ASI10 Rogue agents

11. Organization & Team Controls

11.1 Deploy Cursor Teams or Enterprise for Centralized Management

Profile Level: L2 (Walk)

Description

Use Cursor Teams or Enterprise edition to enforce organizational policies, manage licenses, and control AI provider access centrally.

Rationale

Why This Matters:

  • Centralized policy enforcement (Privacy Mode, allowed providers, MCP servers)
  • License management and usage tracking
  • Audit logging at organization level
  • Over half of Fortune 500 now use Cursor — enterprise governance is critical
  • Several controls in this guide have no self-serve equivalent: model governance via Cursor Router (2.2), extension allowlisting (8.1), Team and Enterprise hooks distribution (11.3), and SCIM (1.4) all require a team plan and, in most cases, Enterprise

Attack Prevented: Policy divergence across individually-configured installations, and the shadow-IT case where developers adopt Cursor on personal accounts entirely outside organizational visibility and control

ClickOps Implementation

Step 1: Set Up Cursor Teams or Enterprise

  1. Visit: https://cursor.com/pricing
  2. Choose plan:
    • Teams ($40/user/month): SSO, org-wide Privacy Mode, usage analytics, shared rules
    • Enterprise (custom pricing): All Teams features plus SCIM, MDM policies, audit logs, CMEK, self-hosted agents, AI Code Tracking API
  3. Create organization and invite team members

Step 2: Configure Organization Policies

  1. In admin dashboard:
    • Privacy Mode: Enforce for all users (cannot be overridden)
    • Allowed AI Models: Restrict to approved models
    • MCP Servers: Configure allowlist
    • Agent Settings: Disable auto-run, require sandbox
    • Extensions: Configure allowlist
    • Telemetry: Disable for all users
    • Cloud Agents: Enable or disable per policy
    • BYOK: Disable if using only org-managed keys

Enterprise-Only Features

Feature Description
SCIM 2.0 Automated user provisioning/deprovisioning
MDM Policies Deploy settings via Jamf, Intune, Kandji
Audit Logs Authentication, settings changes, API key management
Log Streaming Export to SIEM (Splunk, Datadog, etc.)
CMEK Customer-managed encryption keys for embeddings
Self-Hosted Agents Cloud agents running in your infrastructure
AI Code Tracking API Per-commit AI attribution (alpha)
Cursor Blame AI vs. human code attribution in git blame
Billing Groups Cross-team spend allocation
Service Accounts Automated workflow authentication

11.2 Enforce Organizational Policies via MDM

Profile Level: L3 (Run)

Description

Use MDM (Mobile Device Management) to deploy and enforce Cursor security settings across all developer machines. MDM-deployed policies cannot be overridden locally.

Rationale

Why This Matters:

  • Without MDM enforcement, developers can disable Privacy Mode, enable auto-run, or install unapproved MCP servers locally
  • 78% of AI coding tool usage is shadow IT — MDM ensures governance even for unmanaged adoption
  • MDM-deployed settings survive Cursor updates and reinstalls
  • MDM is the layer that wins conflicts: the AllowedExtensions MDM key overrides the dashboard-configured extension allowlist, so where both exist the MDM value is what is actually enforced

Attack Prevented: Local reversal of organizational security settings by a developer or by malware acting with the developer’s privileges, and authentication with personal Cursor accounts on corporate devices to escape organizational policy entirely

Prerequisites

  • Cursor documents advanced identity controls — “SCIM, MDM policies, and more” — as available on Enterprise. Confirm MDM policy entitlement for your specific plan with Cursor before designing around it.

ClickOps Implementation

Step 1: Create MDM Configuration Profile

Use the exact policy keys Cursor documents. The client setting and the MDM key are different identifiers for the same control — searching Cursor settings for the client setting is how you verify the MDM key landed:

Control Client setting MDM policy key
Restrict login to your team cursorAuth.allowedTeamId AllowedTeamId
Extension allowlist extensions.allowed AllowedExtensions
Workspace trust security.workspace.trust.enabled WorkspaceTrustEnabled
  1. AllowedTeamId takes a comma-separated list of permitted team IDs. Cursor documents the enforcement behaviour explicitly: a user authenticating with a team ID outside the list is forcefully logged out immediately, an error is displayed, and further authentication attempts are prevented until a valid team ID is used. This is what stops a personal account being used on a corporate device
  2. AllowedExtensions controls permitted extensions and overrides the dashboard allowlist (8.1)
  3. WorkspaceTrustEnabled force-enables workspace trust (7.1), which Cursor ships disabled by default — this is the highest-value single key in the profile
  4. Add Privacy Mode (2.1) and telemetry (9.1) enforcement alongside them

Step 2: Deploy via MDM

  • macOS (Jamf/Kandji): Deploy as .mobileconfig XML profile
  • Windows (Intune/SCCM): Deploy equivalent Group Policy Objects
  • Linux: Deploy via configuration management (Ansible, Puppet, Chef)

Step 3: Distribute Compliance Hooks

  1. Use Cursor Hooks to enforce compliance policies at runtime — see 11.3 for the event model, precedence, and enterprise file paths
  2. Hooks can block unapproved commands and modify tool inputs, which is enforcement rather than advice
  3. Deploy the enterprise-scope hooks.json through MDM alongside editor settings, or distribute team hooks through the dashboard

Time to Complete: ~2 hours (initial setup), ongoing maintenance for policy updates

Validation & Testing

  1. On a managed machine, attempt to sign in with a personal Cursor account and confirm the forced logout and error
  2. Search Cursor settings for security.workspace.trust.enabled and confirm it reads as enabled and is not locally editable
  3. Attempt to install an extension outside the allowlist and confirm it is blocked
  4. Confirm the client version meets the 2.1+ floor required for extension restrictions (8.1)

11.3 Deploy Cursor Hooks as an Enforcement Layer

Profile Level: L2 (Walk) NIST 800-53: AC-3, AU-2, SI-4, CM-7

Description

Cursor Hooks are scripts that observe, control, and extend the agent loop. They are spawned processes that exchange JSON over stdio before and after defined agent stages, and — critically — they can block an action or modify its input. Where Run Modes are described by the vendor as best-effort guardrails (5.1), hooks are the layer where an organization can impose a deterministic decision on what the agent is allowed to do.

Rationale

Why This Matters:

  • Hooks are the only Cursor-native mechanism that can deny a specific agent action programmatically: returning "permission": "deny" or exiting with code 2 blocks the action, while "updated_input" fields rewrite tool inputs before execution
  • They cover the exact chokepoints that every attack in Appendix B passes through — shell execution, MCP calls, file reads, file edits, and prompt submission — so a single hook can neutralize a class of attack rather than a single CVE
  • They are the enforceable answer to prompt injection: an injected instruction may convince the model, but it does not convince the hook process, which sees the concrete tool call rather than the persuasive text
  • Precedence is explicit and top-down — Enterprise → Team → Project → User — so an organizational hook cannot be overridden by a project or a developer, which is what makes them a control rather than a convention
  • Fail-open is the default. An exit code other than 0 or 2 allows the action. A hook that crashes therefore permits what it was written to block — hooks must be tested for their failure behaviour, not just their success path
  • Untested hooks add latency to every agent interaction, so scoping them to the events that matter is a usability requirement as well as a performance one

Attack Prevented: Prompt-injection-driven shell execution and MCP tool invocation, exfiltration of secrets through agent-initiated commands, unreviewed edits to sensitive files, and per-developer divergence from organizational agent policy

Prerequisites

  • Enterprise plan for dashboard-distributed team and enterprise-managed hooks
  • Ability to deploy files to developer endpoints for the enterprise-scope path, or MDM (11.2)
  • A tested hook script, including its behaviour when it errors

ClickOps Implementation

Step 1: Choose the scope, and understand precedence

Precedence runs Enterprise → Team → Project → User (highest to lowest). Place organizational policy at Enterprise or Team so it cannot be overridden locally.

Scope Location
Enterprise (macOS) /Library/Application Support/Cursor/hooks.json
Enterprise (Linux/WSL) /etc/cursor/hooks.json
Enterprise (Windows) C:\ProgramData\Cursor\hooks.json
Team Configured in the Cursor web dashboard and distributed automatically
Project <project-root>/.cursor/hooks.json
User ~/.cursor/hooks.json

Step 2: Hook the events that carry risk

Cursor documents these events. Start with the security-relevant subset rather than instrumenting everything:

Class Events Security use
Shell beforeShellExecution, afterShellExecution Deny dangerous commands; this is the chokepoint Run Modes only guard on a best-effort basis
MCP beforeMCPExecution, afterMCPExecution Enforce a real MCP tool policy independent of the approval prompt (4.2)
Files beforeReadFile, afterFileEdit Block reads of credential paths; audit or reject edits to sensitive files
Prompt beforeSubmitPrompt Scrub secrets from outbound prompts before they leave the machine
Tools preToolUse, postToolUse, postToolUseFailure General-purpose policy and telemetry across all tool calls
Session sessionStart, sessionEnd, stop, preCompact Session-scoped audit records
Subagents subagentStart, subagentStop Apply the same policy to delegated agents, which otherwise inherit trust silently
Agent output afterAgentResponse, afterAgentThought Response-side monitoring
Tab beforeTabFileRead, afterTabFileEdit Extend file policy to inline completions, which are a separate data path from chat
Lifecycle workspaceOpen Workspace-entry checks, complementing workspace trust (7.1)

Step 3: Write hooks that fail closed

  1. Return "permission": "deny" or exit 2 to block; any other non-zero exit allows the action by default
  2. Wrap hook logic so that an unexpected error still results in a deny for security-critical events, rather than relying on the default
  3. Keep hooks fast — they run in the agent loop, on every matching event

Step 4: Distribute and keep them in sync

  1. On Enterprise, configure team and enterprise-managed hooks through the web dashboard; Cursor documents automatic synchronization to all team members every thirty minutes
  2. Budget for that sync interval in your incident response: a hook change pushed to block an active attack is not instantaneous across the fleet, so pair urgent changes with the MDM-deployed enterprise file
  3. Put .cursor/hooks.json under CODEOWNERS review (6.2) — a project hook is executable policy and deserves the same review as a rules file

Validation & Testing

  1. Trigger a command your beforeShellExecution hook should block and confirm it is denied
  2. Deliberately make the hook exit with a code other than 0 or 2 and confirm you understand the resulting fail-open behaviour — then fix it if the event is security-critical
  3. Set a conflicting hook at Project scope and confirm the Enterprise or Team hook still wins
  4. Confirm a dashboard-distributed hook reaches a test machine, and record the observed sync delay
  5. Confirm hooks apply to subagent activity, not just the top-level agent

Compliance Mappings

Framework Control ID Control Description
NIST 800-53 AC-3 Access enforcement
NIST 800-53 CM-7 Least functionality
NIST 800-53 AU-2 Event logging
NIST 800-53 SI-4 System monitoring
OWASP LLM LLM01 Prompt injection
OWASP Agentic ASI02 Tool misuse
OWASP Agentic ASI06 Code execution controls

Appendix A: Edition Compatibility

Control Cursor Free Cursor Pro Cursor Teams Cursor Enterprise
Account Authentication (1.1)
MFA (1.2)
SSO/SAML (1.3)
SCIM Provisioning (1.4)
Privacy Mode (2.1) ✅ (opt-in) ✅ (opt-in) ✅ (enforceable) ✅ (enforceable)
US-only data residency (2.1) ✅ (per team, via account team, 10% model uplift)
Cursor Router model governance (2.2) ✅ (on by default) ✅ (admin-enabled)
.cursorignore (2.3)
Local Models (2.4)
MCP Allowlisting (4.1) Manual Manual Manual ✅ Centralized
MCP Tool Protection (4.2)
Disable Auto-Run (5.1) ✅ (enforceable)
Agent Approval & Network Posture (5.2) ✅ (enforceable)
Self-Hosted Agents (5.3)
Rules File Audit (6.1)
Workspace Trust (7.1) ✅ (enforceable)
Extension Allowlist (8.1)
Telemetry Control (9.1)
Audit Logs (10.1) Basic ✅ Full
Log Streaming (10.1)
Organization Policies (11.1) Partial
MDM Enforcement (11.2)
Hooks — User/Project scope (11.3)
Hooks — Team/Enterprise distribution (11.3) ✅ (dashboard, ~30 min sync)
CMEK (11.1)
AI Code Tracking API (11.1) ✅ (alpha)

Appendix B: Security Incidents and CVEs

Date CVE/ID Name Severity Description Fixed In
Mar 2025 None Rules File Backdoor High Hidden Unicode in .cursorrules injects invisible backdoors (Pillar Security) Attack class
Jun 2025 None Malicious Extension High Fake Solidity extension on Open VSX → $500K crypto theft (Kaspersky) Removed
Aug 2025 CVE-2025-54135 CurXecute 8.6 RCE via MCP prompt injection (AIM Security) v1.3
Aug 2025 CVE-2025-54136 MCPoison 7.2 Persistent MCP trust bypass (Check Point) v1.3
Sep 2025 None Workspace Trust Bypass High Auto-exec via disabled Workspace Trust (Oasis Security) Design choice
Sep 2025 CVE-2025-59944 Case-Sensitivity Bypass 8.0 File protection bypass on macOS/Windows (Lakera) v1.7
Sep 2025 CVE-2025-61590 Workspace RCE High RCE via .code-workspace files (Geordie AI) v1.7
Sep 2025 CVE-2025-61591 OAuth MCP Impersonation High MCP server impersonation via OAuth (Geordie AI) v1.7
Sep 2025 CVE-2025-61592 CLI Config Exploit High RCE via manipulated CLI config (Geordie AI) v1.7
Sep 2025 CVE-2025-61593 CLI Agent Overwrite High Sensitive file overwrite via CLI agent (Geordie AI) v1.7
Nov 2025 GHSA-vhc2-fjv4-wqch Cursorignore Bypass Medium AI agents read files protected by .cursorignore Cursor 1.7.23
Nov 2025 CVE-2025-64106 MCP Install Trust 8.8 MCP deep-link handling trust bypass (Cyata) Patched
Dec 2025 None Extension Recommendation Medium IDE recommends non-existent extensions on Open VSX (Koi Security) Dec 1, 2025
Dec 2025 GHSA-82wg-qcm4-fp2w Terminal Allowlist Bypass High Environment variable manipulation bypasses command denylist Patched
2025 None NomShub Critical Persistent remote access via sandbox breakout (Straiker) v3.0
2026 CVE-2026-22708 Shell Builtin Bypass High Shell builtins bypass command allowlist for sandbox escape (Straiker) Patched
Ongoing 94+ CVEs Chromium N-Days Various Cursor runs Chromium 6 major versions behind; 94+ unpatched CVEs (OX Security) Unresolved

Minimum safe version: Cursor 1.7+ (patches all September 2025 CVEs). Recommended: latest stable release.


Appendix C: Compliance Framework Mappings

OWASP Top 10 for LLM Applications (2025)

OWASP LLM ID Risk Guide Controls
LLM01 Prompt Injection 4.1, 4.2, 5.1, 6.1, 6.2, 7.1
LLM02 Sensitive Information Disclosure 2.1, 2.3, 3.1, 7.2, 9.1
LLM03 Supply Chain 4.1, 6.1, 8.1
LLM05 Improper Output Handling 5.1, 7.2
LLM06 Excessive Agency 4.2, 5.1, 5.2, 5.3

OWASP Top 10 for Agentic Applications (2026)

OWASP Agentic ID Risk Guide Controls
ASI01 Agent Goal Hijacking 5.1, 6.1, 7.1
ASI02 Tool Misuse 4.2, 5.1
ASI03 Identity and Privilege Abuse 4.2, 5.1, 5.2
ASI04 Memory Poisoning 6.1, 6.2
ASI05 Supply Chain Risks 4.1, 8.1
ASI06 Code Execution 5.1, 5.2
ASI10 Rogue Agents 10.2

NIST AI RMF and MITRE ATLAS

Framework Reference Guide Controls
NIST AI RMF GOVERN 1.4 AI deployment controls 2.4, 5.3, 11.1
NIST AI RMF GOVERN 1.7 AI data governance 2.1, 2.3
NIST AI RMF MAP 1.5 Risk characterization 4.1
NIST AI RMF MANAGE 1.3 Deployment risk mgmt 5.3, 11.1
NIST SP 800-218A PW.5.1 Injection prevention 4.1, 6.1
NIST SP 800-218A PW.7.1 Code review 6.2
MITRE ATLAS AML.T0051 LLM prompt injection 6.1, 7.1
MITRE ATLAS AML.T0061 AI agent tools 5.1, 5.2
MITRE ATLAS AML.T0063 Poisoned AI agent tool 4.1

Appendix D: References

Official Cursor Documentation:

Currency note (2026-08). Cursor ships faster than a guide revision cycle. Two source URLs cited by earlier revisions of this guide now return 404 — the agent sandboxing documentation and the audit-logs documentation — and the claims that depended on them are annotated in 5.2 and 10.1 rather than asserted. Cursor’s Trust Center and /security marketing page have been removed from this list under the repository’s source standard: they describe certifications, not configuration. Cursor also carries a known Tier 3 exposure gap in this repository’s source coverage; independent research beyond the incidents in Appendix B was not re-surveyed in this pass and warrants a dedicated search budget.

Third-Party Benchmarks:

  • No CIS Benchmark, DISA STIG, or CISA SCuBA baseline exists for Cursor as of 2026-08. Compliance mappings in this guide are to NIST 800-53, SOC 2, ISO 27001, OWASP LLM/Agentic, NIST AI RMF, and MITRE ATLAS by name.

VSCode Security (Cursor inherits):

CVE and Vulnerability Research:

Industry Frameworks:

Government Guidance:

Community Resources:


Changelog

Date Version Maturity Changes Author
2026-08-08 0.4.0 draft Add 11.3 Cursor Hooks as an enforcement layer (event classes, Enterprise→Team→Project→User precedence, per-platform config paths, fail-open default, ~30 min dashboard sync). Rewrite 2.2 around Cursor Router model governance (on by default for Teams; routed model hidden by default; mode restrictions; soft/hard enforcement). Add US-only data residency and restricted-model retention approvals to 2.1. Replace the 9.2 endpoint table with Cursor’s documented hosts, add *.cursorvm.com cloud-agent VMs, and remove *.cursor.com and marketplace.visualstudio.com (not in the vendor list). Correct exact identifiers in 1.4, 7.1, 8.1, 11.2 (cursorAuth.allowedTeamId/AllowedTeamId, extensions.allowed/AllowedExtensions with MDM override and 2.1+ version floor, security.workspace.trust.enabled/WorkspaceTrustEnabled, three roles, SCIM requires Enterprise with SSO). Reframe 4.2, 5.1, and 5.2 around the current approval-tier model and quote the vendor’s “best-effort guardrails rather than a hard security boundary” caveat. Soften 5.2 sandbox internals and 10.1 audit-log specifics — both source URLs now 404, annotated rather than asserted. Add missing Attack Prevented to 2.2, 2.4, 4.2, 5.2, 6.2, 9.1, 10.1, 10.2, 11.1, 11.2, 11.3. Remove Trust Center and /security marketing references Claude Code (Opus 4.8)
2026-06-29 0.3.1 draft Add cheat-sheet Description and Rationale for all controls Claude Code (Opus 4.8)
2026-04-15 0.3.0 draft [SECURITY] Major update: add MCP Server Security (sec 4), Agent & Sandbox Security (sec 5), Rules File Security (sec 6), SSO/SCIM (1.3-1.4), .cursorignore (2.3), extension supply chain (8.1), agent monitoring (10.2), MDM enforcement (11.2). Update Security Incidents appendix with 12+ new CVEs/vulns. Add OWASP Agentic/LLM, NIST AI RMF, MITRE ATLAS compliance mappings. Update edition compatibility for Teams/Enterprise tiers. Create 12 code pack files. Claude Code (Opus 4.6)
2026-02-19 0.2.0 draft Migrate all inline code blocks to Code Packs (sections 2.1, 3.1, 3.2, 3.3, 4.2, 7.1) Claude Code (Opus 4.6)
2025-12-15 0.1.0 draft Initial Cursor hardening guide Claude Code (Opus 4.5)

Contributing

Found an issue or want to improve this guide?


Questions or feedback?

  • GitHub Discussions: [Link]
  • GitHub Issues: [Link]

Built with focus on securing AI-powered development tools while maintaining developer productivity.