Browse Source

fix: use try-catch on insert to handle TOCTOU username race condition

Replaced select-then-insert with direct insert wrapped in try-catch.
The UNIQUE constraint on username catches duplicate registrations
atomically, returning a clean error message instead of leaking
a raw DB exception.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
feat/registration-page
npmrun 2 weeks ago
parent
commit
4d507df75d
  1. 14
      server/api/auth/register.post.ts

14
server/api/auth/register.post.ts

@ -2,7 +2,7 @@ import { registerSchema } from '../../utils/auth/validation'
import { verifyCaptcha } from '../../utils/auth/captcha'
import { dbGlobal } from 'drizzle-pkg/lib/db'
import { users } from 'drizzle-pkg/lib/schema/auth'
import { eq } from 'drizzle-orm'
import { hash } from 'bcryptjs'
export default defineWrappedResponseHandler(async (event) => {
@ -19,16 +19,9 @@ export default defineWrappedResponseHandler(async (event) => {
return R.error('验证码错误或已过期', null)
}
const existing = await dbGlobal
.select()
.from(users)
.where(eq(users.username, username))
if (existing.length > 0) {
return R.error('用户名已存在', null)
}
const hashedPassword = await hash(password, 10)
try {
const result = await dbGlobal
.insert(users)
.values({
@ -40,4 +33,7 @@ export default defineWrappedResponseHandler(async (event) => {
.returning({ id: users.id })
return R.success({ id: result[0].id, username })
} catch {
return R.error('用户名已存在', null)
}
})

Loading…
Cancel
Save