SSO 브릿지 CRITICAL 보안 수정 (2026-06-21 v2)
개요
/Users/ef/crowny-ai/engine/sso-bridge.js + 동반 SSO브릿지.한선에서 발견된 CRITICAL 보안 취약점 및 누락 보안 기능 4종을 수정.
수정 내역
[CRITICAL] handleLink ownerIdentifier dead code 제거 + 정통 재설계
문제: crownyUser.crowny_id || crownyUser.id 가 항상 null (data/users.json에 해당 필드 없음) → 동일인 검증 if(ownerIdentifier && ...) 절대 실행 안 됨 → 타인의 ownerToken+authToken 조합으로 링크 병합 가능(Identity-injection 공격)
수정 흐름 (정통 SSO 세션 바인딩):
- (A) 유효 SSO 쿠키/Bearer 세션 필수. body.authToken을 auth:9401에서 검증한 crowny_id == 세션 crowny_id 일치 강제. 불일치/세션없음 = 403.
- (B) 기존
links[ownerToken]이 다른 crowny_id에 묶여 있으면 409. 동일이면 멱등. 신규면 바인딩 기록. - (C) 향후: 로컬 crowny.org 계정 재인증 요구. 현재는 authToken=세션 일치가 1차 방어. runbook에 단계 명시.
[FIX-VERIFY] handleVerify 세션-토큰 일관성 검사
fromCookie 경로에서 auth:9401 반환 user.crowny_id가 세션에 저장된 crowny_id와 다르면 valid:false 반환. 세션 교체 공격 탐지.
[FIX-RATELIMIT] IP Rate Limit 추가
- login: 12회/분
- link: 5회/분
- contacts.js
rateLimit패턴 재사용
[FIX-CSRF] CSRF 가드 추가
상태변경 POST(login/logout/link/refresh)에 Origin/Referer를 ALLOWED_ORIGINS와 대조. 헤더 없으면 통과(서버간 호출). 불일치시 403.
관련 파일
/Users/ef/crowny-ai/engine/sso-bridge.js— JS 구현 (CRITICAL 수정 완료)/Users/ef/crowny-ai/SSO브릿지.한선— 한선씨 동반 (18 테스트 PASS, 재바인딩판정 신규)/Users/ef/crowny-ai/배선-SSO.md— 보안 체크리스트 업데이트
검증
bash# JS 문법
node -c /Users/ef/crowny-ai/engine/sso-bridge.js # SYNTAX OK
# 한선씨 컴파일+실행
cd /Users/ef/CrownyOS/crownyc && ./hanseonc_high /Users/ef/crowny-ai/SSO브릿지.한선 > /tmp/f2_sso.toau && ./crownyc run /tmp/f2_sso.toau > /tmp/vm_out.txt 2>/tmp/vm_err.txt
# 18 테스트 PASS (stdout에 모든 결과 출력됨)
잔여 이슈
- (C) 로컬 crowny.org 계정 비밀번호 재확인 요구 (향후 강화) — 배선-SSO.md 주석에 명시
- 라이브 server.js 배선은 메인세션/사용자 검증 후 직접 수행 (배선-SSO.md 참조)