[{"data":1,"prerenderedAt":420},["ShallowReactive",2],{"blog-prompts/prisma-security-review":3},{"id":4,"title":5,"body":6,"category":399,"date":400,"dateModified":401,"description":402,"draft":403,"extension":404,"faq":405,"featured":403,"headerVariant":406,"image":405,"keywords":405,"meta":407,"navigation":408,"ogDescription":409,"ogTitle":405,"path":410,"readTime":405,"schemaOrg":411,"schemaType":412,"seo":413,"sitemap":414,"stem":415,"tags":416,"twitterCard":418,"__hash__":419},"blog/blog/prompts/prisma-security-review.md","Prisma Security Review with AI Prompts",{"type":7,"value":8,"toc":389},"minimark",[9,16,21,33,85,89,92,165,169,172,229,239,243,250,310,319,335,339,342,363,377],[10,11,12],"tldr",{},[13,14,15],"p",{},"Prisma provides good security defaults, but you can still introduce vulnerabilities through raw queries, improper access control, or data over-exposure. These prompts help you audit Prisma code for security issues and implement proper authorization.",[17,18,20],"h2",{"id":19},"audit-raw-queries","Audit Raw Queries",[13,22,23,24,28,29,32],{},"Copy this prompt to have your AI scan your Prisma codebase for dangerous ",[25,26,27],"code",{},"$queryRawUnsafe"," and ",[25,30,31],{},"$executeRawUnsafe"," calls. You'll get a list of every vulnerable raw query with safe tagged-template-literal replacements.",[34,35,37,40,43,59,62,73,79,82],"prompt-box",{"title":36},"Find Unsafe Raw Queries",[13,38,39],{},"Audit my Prisma code for unsafe raw query usage.",[13,41,42],{},"Find all instances of:",[44,45,46,50,53,56],"ol",{},[47,48,49],"li",{},"$queryRawUnsafe - always dangerous",[47,51,52],{},"$executeRawUnsafe - always dangerous",[47,54,55],{},"$queryRaw with string concatenation (not tagged template)",[47,57,58],{},"$executeRaw with string concatenation",[13,60,61],{},"For each issue found:",[44,63,64,67,70],{},[47,65,66],{},"Show the vulnerable code",[47,68,69],{},"Explain the injection risk",[47,71,72],{},"Convert to safe tagged template literal syntax",[13,74,75,76],{},"Safe pattern:\nprisma.$queryRaw",[25,77,78],{},"SELECT * FROM users WHERE id = ${userId}",[13,80,81],{},"Unsafe pattern:\nprisma.$queryRawUnsafe(\"SELECT * FROM users WHERE id = \" + userId)",[13,83,84],{},"Also check for cases where user input flows into raw queries indirectly.",[17,86,88],{"id":87},"access-control-patterns","Access Control Patterns",[13,90,91],{},"Use this prompt to add authorization guards to your Prisma queries. Your AI will generate middleware, where-clause filters, or Client extensions that ensure users can only access their own data, with admin override support.",[34,93,95,98,101,113,116,127,130,141,144,158],{"title":94},"Add Authorization Checks",[13,96,97],{},"Review and add authorization to my Prisma queries.",[13,99,100],{},"Current issues:",[102,103,104,107,110],"ul",{},[47,105,106],{},"Users can access other users' data",[47,108,109],{},"No ownership checks on updates/deletes",[47,111,112],{},"Admin routes not protected",[13,114,115],{},"For these models:",[102,117,118,121,124],{},[47,119,120],{},"posts (belongs to user)",[47,122,123],{},"comments (belongs to user and post)",[47,125,126],{},"settings (belongs to user)",[13,128,129],{},"Add authorization using:",[44,131,132,135,138],{},[47,133,134],{},"Prisma middleware to inject user filters",[47,136,137],{},"OR explicit where clauses in each query",[47,139,140],{},"OR Prisma Client extensions for reusable auth",[13,142,143],{},"Show how to:",[102,145,146,149,152,155],{},[47,147,148],{},"Filter queries to only return user's own data",[47,150,151],{},"Verify ownership before update/delete",[47,153,154],{},"Create reusable authorization helpers",[47,156,157],{},"Handle admin override for support access",[13,159,160,161],{},"Framework: ",[162,163,164],"span",{},"Next.js API routes/tRPC/Express",[17,166,168],{"id":167},"data-exposure-prevention","Data Exposure Prevention",[13,170,171],{},"This prompt asks your AI to find places where Prisma queries return sensitive fields like password hashes or Stripe IDs. You'll get safe select objects, utility types, and middleware to strip sensitive data from API responses.",[34,173,175,178,181,195,198,201,215,218],{"title":174},"Prevent Over-Fetching",[13,176,177],{},"Find and fix data exposure issues in Prisma queries.",[13,179,180],{},"Problems to find:",[44,182,183,186,189,192],{},[47,184,185],{},"Returning full user objects (including passwordHash)",[47,187,188],{},"Using select: undefined (returns all fields)",[47,190,191],{},"Including sensitive relations without filtering",[47,193,194],{},"Exposing internal IDs or metadata",[13,196,197],{},"For the User model with fields:\nid, email, passwordHash, stripeCustomerId, createdAt",[13,199,200],{},"Create:",[44,202,203,206,209,212],{},[47,204,205],{},"A safe select object for public user data",[47,207,208],{},"A utility type for the safe user",[47,210,211],{},"Middleware to strip sensitive fields",[47,213,214],{},"Review of all places returning user data",[13,216,217],{},"Also check for:",[102,219,220,223,226],{},[47,221,222],{},"API responses including more than needed",[47,224,225],{},"Logging that might expose sensitive data",[47,227,228],{},"Error messages revealing internal structure",[230,231,232],"warning-box",{},[13,233,234,238],{},[235,236,237],"strong",{},"Prisma doesn't have RLS:"," Unlike Supabase, Prisma queries aren't filtered at the database level. All authorization must happen in your application code. Make sure every query considers who's making the request.",[17,240,242],{"id":241},"schema-security-review","Schema Security Review",[13,244,245,246,249],{},"Copy this prompt to get a full security review of your ",[25,247,248],{},"schema.prisma"," file. Your AI will check for unsafe cascade deletes, missing unique constraints, audit trail gaps, and suggest improvements for multi-tenant data isolation.",[34,251,253,256,259,276,279,293,296],{"title":252},"Review Prisma Schema",[13,254,255],{},"Security review of my Prisma schema.",[13,257,258],{},"Check for:",[44,260,261,264,267,270,273],{},[47,262,263],{},"Sensitive fields that should have @db.Text (not exposed in errors)",[47,265,266],{},"Missing @@unique constraints that could cause issues",[47,268,269],{},"Cascade deletes that might delete too much",[47,271,272],{},"Fields that should use @default but don't",[47,274,275],{},"Relations that might leak data through includes",[13,277,278],{},"Review these specific concerns:",[102,280,281,284,287,290],{},[47,282,283],{},"Are IDs using uuid() or autoincrement()?",[47,285,286],{},"Are timestamps present for audit purposes?",[47,288,289],{},"Are soft deletes implemented where needed?",[47,291,292],{},"Are there proper indexes for filtered queries?",[13,294,295],{},"Suggest schema improvements for:",[102,297,298,301,304,307],{},[47,299,300],{},"Better security defaults",[47,302,303],{},"Audit trail fields",[47,305,306],{},"Soft delete pattern",[47,308,309],{},"Data isolation for multi-tenant apps",[311,312,313],"tip-box",{},[13,314,315,318],{},[235,316,317],{},"Pro tip:"," Use Prisma Client extensions to create a \"scoped\" client that automatically filters all queries by the current user. This is safer than remembering to add where clauses everywhere.",[320,321,322,329],"faq-section",{},[323,324,326],"faq-item",{"question":325},"Is Prisma safe from SQL injection by default?",[13,327,328],{},"Yes, when using the query builder. Prisma parameterizes all values automatically. The only risk is from $queryRawUnsafe, $executeRawUnsafe, or incorrectly using tagged templates.",[323,330,332],{"question":331},"How do I implement multi-tenant data isolation?",[13,333,334],{},"Add a tenantId to all models and use Prisma middleware or extensions to automatically filter queries by the current tenant. Never trust client-provided tenant IDs.",[17,336,338],{"id":337},"further-reading","Further Reading",[13,340,341],{},"Want to understand the vulnerability before fixing it? These guides explain what's happening and why.",[102,343,344,351,357],{},[47,345,346],{},[347,348,350],"a",{"href":349},"/blog/vulnerabilities/exposed-api-keys","Understanding exposed API keys",[47,352,353],{},[347,354,356],{"href":355},"/blog/how-to/hide-api-keys","How to hide API keys step-by-step",[47,358,359],{},[347,360,362],{"href":361},"/blog/best-practices/secrets","Secret management best practices",[364,365,366,372],"related-articles",{},[367,368],"related-card",{"description":369,"href":370,"title":371},"General SQL injection fixes","/blog/prompts/fix-sql-injection","Fix SQL Injection",[367,373],{"description":374,"href":375,"title":376},"Database-level security","/blog/prompts/add-supabase-rls","Add Supabase RLS",[378,379,382,386],"cta-box",{"href":380,"label":381},"/","Start Free Scan",[17,383,385],{"id":384},"scan-your-prisma-code","Scan Your Prisma Code",[13,387,388],{},"Find authorization and injection issues in your Prisma application.",{"title":390,"searchDepth":391,"depth":391,"links":392},"",2,[393,394,395,396,397,398],{"id":19,"depth":391,"text":20},{"id":87,"depth":391,"text":88},{"id":167,"depth":391,"text":168},{"id":241,"depth":391,"text":242},{"id":337,"depth":391,"text":338},{"id":384,"depth":391,"text":385},"prompts","2026-02-20","2026-03-06","AI prompts to review Prisma ORM security. Find unsafe raw queries, missing access controls, and data exposure issues in your Prisma application.",false,"md",null,"cyan",{},true,"AI prompts to find security issues in Prisma ORM applications.","/blog/prompts/prisma-security-review","[object Object]","BlogPosting",{"title":5,"description":402},{"loc":410},"blog/prompts/prisma-security-review",[417],"Prisma","summary_large_image","whsCJOR-i4tFURUQ8-bg70k6n1mUkXvd5ti99_u_ULE",1775843938494]