动态标识符和 Unsafe API 可在输入边界错误时执行注入的 SQL
原文依据:3 处参考资料展示 Prisma.raw(column) 和 $queryRawUnsafe。文档确实警告前者不能用于用户输入,并把后者标为注入风险,但这些 API 本身不会安全转义动态 SQL 结构;代理若错误地把请求参数用于表名、列名或拼接语句,数据库会把注入内容当作 SQL 执行。
攻击者可能读取、修改或删除数据库中该连接账号有权访问的数据。
候选所述注入机制在误用时成立,但原文没有指示把不受信任输入传给这些 API。动态标识符示例使用固定字符串并明确说用户输入不安全;Unsafe 示例也标注仅限可信输入,随后把字符串拼接明确列为漏洞,并给出参数化写法。因此这是安全边界说明和反例,而非鼓励执行注入 SQL。用户仍可要求生成代码避免 `Prisma.raw()` 接收请求值,并优先使用参数化模板。
这项判断针对展示的代码和适用条件,不表示风险已经实际发生。### 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"````查看另外 2 个位置
## $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}'`)```