QA: SPRINT-006 review iteration 1 — FAILED (blocking 5, 2 critical)
This commit is contained in:
52
.qa/SPRINT-006-review-1.md
Normal file
52
.qa/SPRINT-006-review-1.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# SPRINT-006 QA Review — Iteration 1
|
||||
|
||||
- **검증일시:** 2026-04-04 15:10 KST
|
||||
- **검증자:** 다랑이 (Evaluator)
|
||||
- **결과:** ❌ FAILED (blocking 5건)
|
||||
|
||||
## 검증 항목
|
||||
|
||||
| 항목 | 결과 |
|
||||
|------|------|
|
||||
| npm install | ✅ |
|
||||
| prisma generate | ✅ |
|
||||
| npm test (backend) | ✅ 26/26 pass |
|
||||
| npm run build (backend) | ✅ |
|
||||
| npm run build (frontend) | ✅ 16 routes |
|
||||
|
||||
## 🔴 Blocking 이슈
|
||||
|
||||
### B1: JWT_SECRET fallback 'changeme' — 3곳 (Critical)
|
||||
- **파일:** auth.service.ts:85, auth.module.ts:22, events.gateway.ts:48
|
||||
- **문제:** JWT_SECRET 미설정 시 'changeme'로 토큰 서명 → 공격자가 유효한 JWT 위조 가능
|
||||
- **모순:** jwt.strategy.ts는 throw하는데 나머지는 fallback → 불일치
|
||||
- **수정:** 3곳 모두 `?? 'changeme'` 제거, ConfigService.getOrThrow 또는 throw 처리
|
||||
|
||||
### B2: User.role 기본값 "admin" (Critical)
|
||||
- **파일:** prisma/schema.prisma
|
||||
- **문제:** 모든 가입자 자동 admin → 초대코드만 알면 SSH restart, 하네스 수정 등 전체 인프라 제어
|
||||
- **수정:** `@default("viewer")` + admin 승격 별도 로직 + AdminController에 RoleGuard 추가
|
||||
|
||||
### B3: WebSocket JWT 실패 시 disconnect 안 함
|
||||
- **파일:** events.gateway.ts:52-53
|
||||
- **문제:** invalid token 시 연결 유지 → 미인증 실시간 데이터 수신
|
||||
- **수정:** catch 블록에서 `client.disconnect()` 호출
|
||||
|
||||
### B4: `throw new Error` → HttpException
|
||||
- **파일:** auth.controller.ts:32
|
||||
- **문제:** refresh token 없을 때 `throw new Error` → 500 반환
|
||||
- **수정:** `throw new BadRequestException('Refresh token required')`
|
||||
|
||||
### B5: register 엔드포인트 rate limit 없음
|
||||
- **파일:** auth.controller.ts:18-20
|
||||
- **문제:** 초대코드 brute-force 가능
|
||||
- **수정:** `@UseGuards(ThrottlerGuard) @Throttle({ default: { limit: 3, ttl: 60000 } })` 추가
|
||||
|
||||
## Non-blocking 이슈 (7건)
|
||||
- N1: refresh token localStorage 평문 (httpOnly cookie 전환 권장)
|
||||
- N2: AuthProvider 토큰 만료 시 자동 refresh 안 함
|
||||
- N3: register에서 refreshToken 미저장
|
||||
- N4: login 후 userId: 0 하드코딩
|
||||
- N5: DTO 서비스 파일 내 정의 (별도 파일 권장)
|
||||
- N6: adminFetch 주석-코드 불일치
|
||||
- N7: refresh secret suffix 방식 → 별도 env 권장
|
||||
Reference in New Issue
Block a user