← 목록
기타 2026-07-30 5KB 읽기 5분

crowny-dex 인증(P0 취약점 수리) — 2026-07-30

개요

dex.crowny.org(9402, LaunchAgent org.crowny.dex.plist)의 모든 쓰기 API가 body의 userId만 믿고 아무나 남 행세로 거래 가능하던 P0 취약점을 수리. crowny-auth/인증서버.한선의 솔트+SHA256 패턴을 DEX서버.한선 안에 동일 방식으로 재구현(가져오기 아님 — 이식).

구현 (모두 /Users/ef/crowny-dex/DEX서버.한선, 한선씨 hanseonc_high)

  • 자격/토큰 전역 배열 + 회원가입() 로그인실행() 토큰발급() 토큰소유자() 인증게이트()
  • POST /api/register {username,password} → 솔트 SHA256 해시 저장 + credentials.tsv 덧쓰기 + 자동 토큰발급
  • POST /api/login {username,password} → 검증 성공 시 토큰(7일 TTL) 발급
  • 서버 기동 시 자격불러오기()로 credentials.tsv를 수동 파서(탭/줄 split, 내장 split 없음)로 복원 → 재기동해도 계정 유지 확인
  • 쓰기 API 7종(/api/swap /api/loan /api/repay /api/p2p /api/orders /api/orders/cancel /api/supply) 진입부에
인증게이트(대상유저, 토큰) 삽입 — 토큰 없음/무효/만료=401, 토큰은 유효하나 body의 유저와 불일치(사칭)=403
  • 토큰 추출: Authorization: Bearer <토큰> 헤더 우선, 없으면 body의 token 필드 (라우터가 원본 요청에서
토큰추출(원본,바디)로 뽑아 각 실행함수에 인자로 전달 — 기존 실행함수들은 바디만 받던 구조라 시그니처 확장)
  • CORS응답()에 401/403/409 상태텍스트 매핑 추가(기존에도 주문취소실행이 403을 반환하고 있었는데
매핑이 없어 실제로는 HTTP 200으로 나가던 잠재 버그도 같이 수정됨)
  • P2P는 borrowerId 본인 명의로만 개설 가능(대여자 아님) — 차용자 인증
  • /api/supply는 9인 보급계정도 동일 회원가입/로그인 절차로 계정을 만들어야 발행 가능하도록 통일(예외 없음)
  • 에이전트 6,561 자동거래는 영향 없음: /api/agents/tick은 내부 함수 에이전트스왑실행()을 직접 호출하고
HTTP 라우팅상 스왑실행()(인증 게이트 적용 대상)을 거치지 않음 — grep으로 별도 경로 확인.

웹 프런트 (web/index.html)

  • 기존 USERlocalStorage guest-XXXX 랜덤 자칭 방식이었음 → 로그인 계정 없으면 빈 문자열(미로그인)로 전환
  • 헤더에 로그인/로그아웃 버튼(#acctBtn), 로그인·회원가입 겸용 모달(#authModal) 추가(기존 크라우니캔버스
CSS 변수만 사용, 새 색 추가 없음)
  • api() 헬퍼가 Authorization: Bearer <TOKEN> 헤더를 자동 첨부하도록 확장
  • 미로그인 상태에서 스왑/주문/취소 시도 시 서버 401 전에 클라이언트에서 먼저 로그인 모달 유도(openAuth())
  • dex_username/dex_token을 localStorage에 저장, 로그아웃 시 제거

QA 실측 (localhost:9713 임시 + 배포 후 공개 9402 재확인)

케이스기대실측
회원가입→로그인→토큰으로 스왑200 성공PASS
토큰 없이 스왑401PASS
A 토큰으로 B의 userId 사칭 스왑403PASS
무효/조작된 토큰401PASS
중복 회원가입409PASS
틀린 비밀번호 로그인401PASS
서버 재기동 후 기존 계정 로그인200(자격 파일 복원 확인)PASS
/api/agents/tick (n=30/50)인증 추가 후에도 정상 처리PASS(processed 정상 반환)
공개 https://dex.crowny.org/health200PASS
스크린샷: /Users/ef/crowny-dex/data/qa_swap_tab.png(스왑 탭, 헤더에 "로그인" 버튼 정상 노출 — 캡처 직후 QA 산출물이라 삭제됨, 필요 시 크라우니AI검증.sh shot로 재생성)

관련 파일

  • /Users/ef/crowny-dex/DEX서버.한선 — 인증 로직 전체(자격/토큰 섹션 + 7개 쓰기핸들러 게이트)
  • /Users/ef/crowny-dex/web/index.html — 로그인/회원가입 모달 + api() 토큰첨부
  • /Users/ef/crowny-dex/data/credentials.tsv — 아이디\t해시\t솔트\t가입시각 (append-only)
  • 참고 패턴 원본: /Users/ef/crowny-auth/인증서버.한선

잔여 이슈

  • /api/_seed, /api/_settime은 여전히 QA 전용 무인증 엔드포인트 — 기존에도 알려진 이슈(DEX CLAUDE.md에
이미 기록됨), 이번 작업 범위 밖이나 실배포 강화 시 반드시 같이 처리 필요.
  • 9인 보급계정(SUPPLY-1~9)도 이제 회원가입이 필요함 — 운영자가 사전에 계정을 만들어둬야 /api/supply 사용 가능
(기존에는 계정 개념 자체가 없었음). 초기 9개 계정 등록 스크립트는 아직 없음 — 다음 세션에서 일괄 등록 필요.
  • 토큰은 메모리 배열에만 존재(재기동 시 전부 무효화, 재로그인 필요) — credentials만 영속화, 세션은 비영속.
장기 운영 시 필요하면 토큰도 파일 영속화 고려.
  • 기존 주문취소(/api/orders/cancel)의 403이 CORS응답 코드매핑 누락으로 실제로는 HTTP 200으로 나가던
잠재 버그를 이번에 같이 수정(401/403/409 매핑 추가) — 별도 회귀 테스트로 재확인 권장.