← 목록
기타 2026-06-28 6KB 읽기 6분

take.crowny.org 자산 설계 3종 — 이미지추적 · JSON최적화 · 보안하드닝

상태: 설계만(미구현·미배포). take.crowny.org 자산으로 등재. 외부배포(takeurban.art)는 현 상황 유지. 결정(2026-06-28): PG=비교만·결제보류 / 백업=한 계정 시험운영 후 2VPS는 이후 / 세 설계=자산 등재. 구현 시 순서·검증항목·한선씨 동반까지 이 문서로 바로 빌드 가능하게 작성.

설계 1 — 이미지 다운로드 추적(워터마킹)

목표: 사용자가 이미지를 다운로드할 때 로그인 id + 다운로드 시간을 이미지/기록에 남겨, 이후 도용 시 추적 가능하게.

3층 구조 (각 한계 명시)

방법강점한계
① 감사로그(서버)인증 다운로드마다 기록최강 증거·쉬움이미지 자체엔 표식 없음
② 가시 워터마크id+시간 반투명 합성(클라 Canvas)즉각 억지·육안추적크롭/스샷 제거
③ 메타 표식JPEG COM마커에 서명 페이로드(순수 바이트)비가시·0의존성재인코딩 소실

데이터 모델

  • data/download_log.jsonl (append-only, 1줄=1다운로드): {ts, owner(=userId), blobId, ip, ua, sig}
  • sig = HMAC_SHA256(TAKE_DL_KEY, owner|blobId|ts) — 사후 위조 판별용.

API 설계

  • GET /api/blob/<id>?dl=1owner 헤더 필수(미인증 403). 처리: ① 감사로그 append ② JPEG면 COM마커에 crowny-dl:owner|ts|sig 삽입(순수 바이트, PNG는 tEXt 청크) ③ 응답.
  • 클라 다운로드 버튼: 원본 → Canvas에 그림 + 우하단 반투명 텍스트(id · YYYY-MM-DD HH:mm) → toBlob → 저장(②). 원본 raw blob 접근은 인증·로그로 봉쇄.
  • 사후 추적: 유출 이미지의 COM마커 또는 로그 대조 → owner·시각 식별, sig로 위조 배제.

한선씨 동반 (설계)

추적표식.한선 — 다운로드 4상 판정 + 서명 계약:
함수 다운로드판정(인증됨, 차단여부)   // 1=허용(티)/0=인증필요(옴)/-1=차단(타)/9=의심(음)
함수 표식페이로드(소유자, 시각)        // "owner|ts" 조립
// 서명 자체(HMAC)는 server.js crypto 위임(한선씨는 판정·조립 SSOT)

검증항목(구현 시)

COM마커 왕복 보존 · 로그 append 멱등 · sig 위조 거부 · 미인증 403 · PNG/JPEG 분기.

솔직한 한계

스크린샷·재압축이면 ②③ 소실. 법적 추적 최강은 ①감사로그. 권장 기본 = ①+②, ③ 선택.


설계 2 — JSON 최적화

현실: JSON은 이미 전체의 0.x%(이미지가 본체). 실효 이득은 용량보다 처리비용.

조치(무위험 순)

  1. 콤팩트 JSONJSON.stringify(o, null, 2)JSON.stringify(o). 공백 제거로 ~20~40%↓. atomicWrite 경유 전부 적용.
  2. 주문 인덱스data/orders/_index.jsonl(1줄=요약 {id,status,createdAt,updatedAt,owner,unanswered}). saveOrder 시 upsert, allOrders()(현재 전 파일 동기 전수읽기)는 인덱스만 읽음 → 목록 O(n 디스크) → O(1 파일). 상세는 조회 시만 개별 로드.
  3. 콜드데이터 압축 — N일 지난 주문/아카이브 특가 .json.gz(또는 크라우니압축기 .ccp). 조회 시 해제.
  4. (규모 시) node:sqlite(Node22 내장, 외부의존성 0) 마이그레이션 경로 — 인덱스·트랜잭션. 지금 불필요.

효과 추정

pretty 제거 ~20-40%↓ · 인덱스로 관리자 목록 응답 급감(현 병목 allOrders 해소) · 0 의존성 유지.

한선씨 동반 (설계)

인덱스는 데이터라 판정 적음. 보관정책.한선 — 압축 대상 4상 판정(티즉시/옴보관/타압축/음삭제후보, 날짜·상태 기준) 정도.

검증항목

인덱스↔실파일 정합 · 콤팩트 전환 후 파싱 회귀0 · 압축 왕복 byte-identical.


설계 3 — 보안 하드닝

현황 실측 — 됨: scrypt·40자 owner토큰·부팅랜덤 관리자세션·경로조작가드(safeId)·업로드검증·번들 data제외. 없음: 레이트리밋·보안헤더·PII평문·로그회전.

모듈 설계

  1. 보안게이트.한선 — 레이트리밋 4상: 로그인/주문 IP별 윈도우 카운트 → 티(허용)/옴(지연·캡차)/타(거절)/음(임시밴). 카운터는 server.js 메모리맵 위임, 판정은 한선씨 SSOT.
  2. 보안헤더 미들웨어(엔진 공통화 가능) — CSP, HSTS, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy. (nginx/stunnel 단에서도 병행)
  3. PII 암호화 — profiles/users의 전화번호·주소·통관번호·이름·입금자명 = AES-256-GCM(키=env TAKE_PII_KEY). 저장 시 암호화·조회 시 복호화. 마이그레이션 스크립트(기존 평문→암호문, 1회). 로그 PII 마스킹.
  4. admin 기본비번 가드 — 부팅 시 비번이 기본값(take1004)이면 경고 로그 + (옵션)기동거부 env.
  5. 로그 회전take.err/take.log 크기상한 회전(자체 구현 or VPS logrotate). 현재 take.err 6.3MB 무한증가 해소.
  6. 보안 감사로그 — 로그인 실패·관리자 액션 기록.
  7. 적대 테스트 — 기존 crowny-spear 규칙엔진으로 공격검증(설계 검증단계 포함).

우선순위(구현 시)

즉시(무위험): admin비번 변경 + 로그회전 → 보안게이트(레이트리밋+헤더) → PII 암호화(마이그레이션 동반).

검증항목

레이트리밋 임계 동작 · 헤더 응답 확인 · PII 왕복 암복호 + 마이그레이션 무손실 · spear 공격 통과.


자산 등재 메모

  • 자산 소유: take.crowny.org (/Users/ef/crowny-take). 외부배포(takeurban.art VPS)는 현 준비상태 유지(자족화·배포.sh 완료, 미실행).
  • 구현 트리거: 사용자 지시 시 이 문서 순서대로. 모두 한선씨 동반 + 검증 후 라이브 반영.
  • 관련: PG 비교(토스/나이스/PayGate 파사드)는 결제 보류 결정 — 별도 자산(요청 문서).