Dynamic identifiers and Unsafe APIs can execute injected SQL when input boundaries are wrong
Source references: 3The reference demonstrates Prisma.raw(column) and $queryRawUnsafe. It does warn that the former is unsafe for user input and labels the latter an injection risk, but these APIs do not safely escape dynamic SQL structure. If an agent feeds request data into a table name, column name, or concatenated statement, the database can execute it as SQL.
An attacker could read, modify, or delete any data accessible to the database account.
The cited injection mechanism is possible if these APIs are misused, but the source does not direct users to pass untrusted input. The identifier example uses a constant and explicitly says user input is unsafe; the Unsafe example says to use trusted input only, and the later concatenation sample is clearly labeled a vulnerability alongside a parameterized form. This is safety guidance and a negative example, not encouragement to execute injected SQL. Users can still require generated code to keep request values out of `Prisma.raw()` and favor parameterized templates.
This assessment concerns the code and conditions shown, not proof that harm has occurred.### Dynamic table/column namesUse `Prisma.raw()` for identifiers (not safe for user input):```typescriptimport { Prisma } from '../generated/client'const column = 'email'const users = await prisma.$queryRaw` SELECT ${Prisma.raw(column)} FROM "User"````Show 2 other places
## $queryRawUnsafe / $executeRawUnsafeFor fully dynamic queries (use with caution!):```typescript// ⚠️ SQL injection risk - only use with trusted inputconst table = 'User'const users = await prisma.$queryRawUnsafe( `SELECT * FROM "${table}" WHERE id = $1`, userId)```## SQL Injection Prevention### Safe (parameterized)```typescript// ✅ User input is parameterizedconst email = userInputconst users = await prisma.$queryRaw` SELECT * FROM "User" WHERE email = ${email}````### Unsafe (concatenation)```typescript// ❌ SQL injection vulnerability!const email = userInputconst users = await prisma.$queryRawUnsafe( `SELECT * FROM "User" WHERE email = '${email}'`)```