전방위 코드 감사 · 5개 분야 병렬

Rinda(앱린다) 프로젝트 감사 리포트

elysia-server · admin · e2e 모노레포 — 보안 · 백엔드 · DB · 프론트 · 인프라
생성일 2026-06-29 브랜치 alpha 방식 5-에이전트 fan-out + 교차검증 오탐 강등 5건
3
Critical (즉시)
7
High (이번 주)
30+
P1·P2 개선
5
오탐 강등/기각

신뢰성 주석 — 각 에이전트가 자기 발견을 직접 코드로 교차검증했습니다. 에이전트가 보고한 P0 오탐 5건(SQL injection·BullMQ 중복·graceful shutdown·workspace 우회·게이트 우회)은 근거 검토 후 강등/기각했습니다. 아래는 확증된 항목만 담았습니다.

🔴 Critical — 즉시 (오늘)

#분야위치문제영향
1인프라/보안elysia-server/Dockerfile:35 COPY .env* ./ · admin/Dockerfile .env 라이브 시크릿 49개(sk-ant-…, AWS AKIA…, Supabase service key, DB_PASSWORD)가 이미지 레이어에 영구 잔존. 런타임 env_file 주입과 별개로 Dockerfile이 또 복사 이미지 유출 = 전 시크릿 유출. Infisical SSOT 위반
2보안nylas.service.ts:1295 Nylas webhook 서명검증 부재 — Paddle·Slack·Toss·SendGrid·AgentMail은 전부 HMAC 검증하나 Nylas만 누락 open/click/reply 추적 이벤트 위조 주입
3인프라.github/workflows/ci.yml:31-33 메인터 6명(최다 커밋 계정 포함) push/PR에 CI 전체 skip → lint·type·build·auth gate 무검증 정적 게이트가 유일 방어선인데 우회

🟠 High — 이번 주

#분야위치문제
4백엔드sequence-email-worker/idempotency.ts:54멱등 marker Redis-only → Redis 장애 시 시퀀스 이메일 중복 발송 (DB UNIQUE 이중방어 없음)
5DBlead-search.service.ts:697,731 · email-replies.service.ts:158사용자 라우트 OFFSET cap 없음 (leads 851k · email 208k row) → 깊은 페이지 full scan
6DBlead-engagement.service.ts:119emails 자기조인 COUNT(DISTINCT)기본 db(32MB)로 → 디스크 spill
7프론트lead-deals.ts:60~172(6곳) · leads.ts:428data as unknown as … 더블 캐스팅(OpenAPI never 우회) → shape 불일치 시 런타임 크래시
8프론트SequenceEnrollmentsTable.tsx · CustomerTableReadonly.tsx수만 row 테이블 가상화 없이 전량 렌더 (자매 CustomerTable은 적용됨)
9프론트/보안public-routes.tsx:117~151/snitcher-test·/manus-test 등 테스트 페이지 인증 없는 public 프로덕션 배포
10백엔드reply-alert.routes.ts:23최근 커밋(4f2558feb) 추가 라우트가 app.ts 미마운트 → 전부 404, 기능 깨짐

보안 / 인증·권한

심각도위치문제
Crit/High#1, #2 참조시크릿 굽기 · Nylas 무서명
Mederror-handler.ts:174~217500 응답에 raw error.message 노출 (prod 게이팅 없음)
Medrate-limit.plugin.ts:17~94rate limiter in-memory Map → 다중 replica에서 한도 ×N (brute-force·AI비용 abuse)
P1WorkspaceEmailAccountsSection · WorkspaceMembersSection삭제·소유권이전 등 파괴적 버튼이 hasPermission 가드 없이 렌더 (add엔 가드 있음)
P1dashboard-admin-routes.tsx:90admin 라우트 2개 명시적 RouteGuard 누락 (layout default-deny에만 의존)
P2webhook.routes.ts:78 · toss-webhook.routes.ts:56secret 미설정 시 검증 스킵 → prod env 강제 필요
양호JWT httpOnly 쿠키 · DOMPurify 21곳 · sql 파라미터화 · check:routes 게이트확인됨

백엔드 API / 서비스

심각도위치문제
P1linkedin-sdr-profile-view-budget.ts:35cap check-then-act 비원자 → race로 초과
P1trial-feature-usage.service.ts:192카운터 SELECT→UPDATE 트랜잭션 밖 → lost update
P2personalized-emails/rate-limit.service.ts:70Promise.all 부분 reject 미처리 → rate-limit 상태 불일치
P2dsar.service.ts:115,308,336부분실패 후 fulfilled 마킹 + 4단계 erasure 트랜잭션 부재 (GDPR)
P2queues.ts:1438,3529CSV export·blog enqueue dedup jobId 없음 → 중복 클릭 2건 처리
P2약 30개 파일모델명 "gemini-3-flash-preview" 하드코딩 (SSOT 위반)

DB / 쿼리 성능

심각도위치문제
P0~P1#5,#6 + sequence-query.service.ts:305 · ui-events.service.ts:181 · buyer-search/analytics.service.ts:374 · activity-log.service.ts:334OFFSET · 기본 db COUNT(DISTINCT) 다수 산재
P1visitor.service.ts:692 · assessment.service.ts:314동적 정렬 OFFSET → 정렬키별 keyset 필요
P1drizzle/0294,0332leads/emails trgm GIN fastupdate=on 미설정 (INSERT burst 권고 위반)
⚠️ 마감마이그 allowlist 0338·0339·03732026-06-30(내일) 만료 → 정리·연장 필요
양호UUID uuidv7() 100% · enum 분리 · 핵심 인덱스 설계확인됨

프론트엔드 (admin)

심각도위치문제
P0#7,#8,#9 참조더블캐스팅 · 비가상화 · public 테스트페이지
P1hooks 11곳 (leads/emails/sequences/dashboard)keepPreviousData(금지) → keyset 무한스크롤
P1SignatureEditorModal.tsx:62 · email-sidebar.tsx:243 · RepliedEmailsList.tsx:308무가드 re-sync effect → 편집 중 입력 덮어씌움/데이터 손실
P1RichSidePanel.tsx동적 리스트 key={idx} → 중간 삭제 시 입력값·포커스 corruption
P1client.ts:615 전역API 경계가 생성 스키마와 분리(generated/schema import 0) → BE 변경 시 컴파일 통과·런타임 drift
P1ImpersonationContext.tsx:31 · SSE 4파일인증/SSE 응답 as any·무검증 단언

인프라 / 빌드 / 품질 / 테스트

심각도위치문제
Crit#1,#3 참조시크릿 굽기 · CI skip 우회
P1Dockerfile:20bun install --frozen-lockfile || bun install 폴백이 무결성 게이트 무력화
P1e2e 전반셀렉터 SSOT(ports) 86% 스펙 우회 · networkidle .catch(()=>{}) ~60곳 무음통과 · waitForTimeout 15곳 · burn-in 전무
P1매출 영역 E2Enetwork-buyers(#9121)·이메일 발송 enqueue·billing tier-deny 분기 스펙 공백
P1소스 트리200줄 초과 1598/4482 파일(36%), 1000줄+ 111개 · production any 86개(auth.macro·paddle 포함)
P2package.json · compose.db.yml"eslint":"*" 미사용 와일드카드(Biome 사용 중) · 로컬 DB 이미지 untagged floating
P2코드 부채@deprecated 53파일 미삭제 · TODO 68건 · console.log 302건
양호alpha/beta 컨테이너핵심 서비스 전부 healthy(직접 점검), Exited(0)는 1회성 job

⚖️ 신뢰성 — 강등/기각된 오탐 5건

에이전트가 P0로 올렸으나 코드 교차검증으로 강등/기각된 항목. 이 리포트의 정밀도를 위해 명시합니다.

권장 착수 순서

임팩트 대비 작업량이 작은 것부터: #1 시크릿 굽기 제거(.dockerignore) → #10 reply-alert 마운트(1줄) → DB allowlist 만료(내일 마감) → #2 Nylas 서명검증 → #5·#6 DB 쿼리. 묶어서 PR 착수 가능합니다.