TL;DR
The #1 Cursor security best practice is reviewing every AI-generated function before committing. All 8 practices below take about 45 minutes. If you only do two of them, do these: check every generated function for hardcoded secrets, and confirm the endpoint actually checks authentication rather than just hiding the button.
"AI generates code fast. Security still needs a human reading it, function by function, before it ships."
Why Cursor Needs Security Best Practices
Cursor writes functional code in seconds. That's the point of it. But a model optimises for code that runs, not code that holds up against someone poking at it, and nothing in the loop closes that gap for you.
The encouraging part is how shallow most of the damage turns out to be. In scans of AI-built apps we see the same short list over and over: a key pasted into the client, an endpoint with no auth check, a table with no policy on it. None of those take long to fix once you know to look.
Best Practice 1: Review Every AI-Generated Function 2 min per function
Speed is where this goes wrong. Get into the habit of reading every generated block before you accept it:
Security Review Checklist for Generated Code
Before accepting Cursor suggestions:
- No hardcoded API keys, tokens, or passwords
- User input is validated before processing
- Database queries use parameterized statements
- Authentication checks exist on protected routes
- Authorization verifies user owns requested resource
- Error messages don't expose internal details
Example: Reviewing an API Endpoint
// Cursor might generate this
app.get('/api/user/:id', async (req, res) => {
const user = await db.query(
`SELECT * FROM users WHERE id = ${req.params.id}`
);
res.json(user);
});
// Fixed with security best practices
app.get('/api/user/:id', authenticate, async (req, res) => {
// Authorization: user can only access their own data
if (req.user.id !== req.params.id && !req.user.isAdmin) {
return res.status(403).json({ error: 'Access denied' });
}
// Parameterized query prevents SQL injection
const user = await db.query(
'SELECT id, email, name FROM users WHERE id = $1',
[req.params.id]
);
if (!user) {
return res.status(404).json({ error: 'Not found' });
}
res.json(user);
});
Best Practice 2: Configure .cursorignore Properly 5 min
Cursor sends code context to AI servers for processing. Protect sensitive files by excluding them from AI context:
# Environment and secrets
.env
.env.*
*.pem
*.key
**/secrets/**
**/credentials/**
# Configuration with sensitive data
config/production.js
firebase-admin*.json
service-account*.json
# Proprietary code (optional)
src/core/algorithms/
lib/proprietary/
# Large files that waste context
node_modules/
dist/
*.log
*.sql
Important: .cursorignore only stops files being sent as AI context. It doesn't stop them being committed to git. You still need a proper .gitignore.
Best Practice 3: Use Secure Prompting Patterns Ongoing
What you ask for is what you get. Say the security requirement out loud in the prompt:
Prompting Patterns That Improve Security
| Instead of | Ask for |
|---|---|
| "Create a login endpoint" | "Create a secure login endpoint with rate limiting, password hashing, and no sensitive data in errors" |
| "Add a delete user function" | "Add a delete user function with authentication check and authorization (admin or self only)" |
| "Query users from database" | "Query users using parameterized statements to prevent SQL injection" |
| "Create file upload" | "Create secure file upload with type validation, size limits, and sanitized filenames" |
Best Practice 4: Enable Privacy Mode 1 min
Privacy Mode stops your code being used for model training. Turn it on for anything commercial:
- Open Cursor Settings (Cmd/Ctrl + ,)
- Navigate to Privacy settings
- Enable "Privacy Mode"
- Verify the privacy indicator appears in the status bar
Enterprise users: Cursor Business plans offer additional privacy controls including the option to use self-hosted models and stricter data retention policies.
Best Practice 5: Validate Environment Variables at Startup 10 min
Generated code reaches for environment variables constantly, and a missing one usually surfaces as a confusing runtime error hours later. Fail loudly at startup instead:
// Validate required environment variables at startup
const requiredEnvVars = [
'DATABASE_URL',
'SESSION_SECRET',
'STRIPE_SECRET_KEY',
];
function validateEnv() {
const missing = requiredEnvVars.filter(
(key) => !process.env[key]
);
if (missing.length > 0) {
console.error('Missing required environment variables:');
missing.forEach((key) => console.error(` - ${key}`));
process.exit(1);
}
}
validateEnv();
Best Practice 6: Test Database Security Before Launch 15 min
If you're pairing Cursor with Supabase or Firebase, test the rules yourself. Never assume they took:
Supabase RLS Testing
-- Test as anonymous user (should fail for protected tables)
SET request.jwt.claim.sub = '';
SELECT * FROM private_data; -- Should return empty or error
-- Test as authenticated user
SET request.jwt.claim.sub = 'user-123';
SELECT * FROM user_data WHERE user_id = 'user-123'; -- Should work
SELECT * FROM user_data WHERE user_id = 'other-user'; -- Should fail
Best Practice 7: Implement Rate Limiting 10 min
Generated APIs almost never come with rate limiting. Add it:
import rateLimit from 'express-rate-limit';
// General API rate limit
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // 100 requests per window
message: { error: 'Too many requests, try again later' }
});
// Stricter limit for auth endpoints
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 5, // Only 5 login attempts per 15 minutes
message: { error: 'Too many login attempts' }
});
app.use('/api/', apiLimiter);
app.use('/api/auth/', authLimiter);
Best Practice 8: Use Cursor Chat for Security Reviews 5 min per review
Point Cursor at your own code and make it argue with you:
// In Cursor Chat, highlight code and ask:
"Review this code for security vulnerabilities including:
- SQL injection
- XSS vulnerabilities
- Authentication bypass
- Authorization issues
- Information disclosure in errors
- Missing input validation"
// Or for specific concerns:
"Does this endpoint properly validate that the
authenticated user owns the resource they are accessing?"
Common Cursor Security Mistakes
| Mistake | Risk | Fix |
|---|---|---|
| Accepting code without review | Vulnerabilities in production | Review every function before committing |
| Hardcoded test credentials | Credential exposure | Always use environment variables |
| No .cursorignore file | Secrets sent to AI servers | Configure .cursorignore immediately |
| Trusting CORS: "*" in generated code | Cross-origin attacks | Specify allowed origins explicitly |
| Missing auth on new endpoints | Unauthorized access | Add auth middleware by default |
Official Resources: For the latest information, see Cursor Documentation, Cursor Privacy Policy, and Cursor Security Overview.
Is Cursor safe for commercial projects?
Yes, with proper configuration. Enable Privacy Mode, configure .cursorignore for your sensitive files, and review AI-generated code before it ships. Plenty of companies run Cursor in production on exactly those terms.
Does Cursor store my code?
Cursor sends code context to AI servers so the model can answer. With Privacy Mode on, that code isn't used for training. Check Cursor's current privacy policy for the specifics on retention and handling, since those terms change.
How do I prevent Cursor from seeing secrets?
Create a .cursorignore file in your project root and add patterns for .env files, key files, and any directories containing sensitive configuration. This prevents these files from being sent as AI context.
Should I use Cursor for security-critical code?
You can use it for anything. Security-critical sections just need a second pair of eyes. Get another developer to read generated authentication, authorization, and data-handling code before it goes out.
Further Reading
Put these practices into action with our step-by-step guides.
Verify Your Cursor Security
Scan your Cursor project for common security issues in AI-generated code.