# Security — 외부로 나가는 순간의 최소선

적용: data-storage ③(외부 서비스)·deploy·인증 구현 시.

- **존재 여부를 노출하는 endpoint(이메일 중복확인 등)는 enumeration 표적**이다. rate limit·인증을 붙일 수 없으면 구현하지 않은 항목을 **skipped로 명시**하라 — "모르는 스킵이 가장 위험하다".
- **개인정보를 GET 쿼리스트링에 싣지 마라** (서버·프록시 로그에 잔존) → POST body로.
- 세션·토큰 쿠키는 `httpOnly` + `sameSite` + (프로덕션) `secure`. 쿠키 값은 불투명 식별자만.
- **비밀번호는 어떤 경로로도 저장·로깅·에코 금지** (스텁·mock 포함). 저장은 해시만.
- 클라이언트 검증(zod)은 UX용이다 — **서버 검증은 별개로 필수**. Supabase 등 외부 서비스를 쓰면 RLS/정책이 그 서버 검증이다.
- 사내 실데이터의 외부 저장·배포 전 사용자 확인은 data-storage·deploy 스킬의 절차를 따른다.

## 개인정보(PII)를 코드에 남기지 않는다

이 앱을 만드는 사람은 기획서·스프레드시트·화면 캡처를 그대로 붙여넣는다. **거기 실제 사람 정보가 섞여 들어오는 것이 기본값**이라고 가정하고 다룬다. PII = 이름·연락처·이메일·주소·소속/직급·평가·연봉·이력서 본문 같은 개인 식별 가능 정보.

- **mock·시드·픽스처·테스트 데이터에 실제 사람 정보를 쓰지 않는다.** 사용자가 실데이터를 붙여넣어 "이걸로 화면 만들어줘"라고 해도, 화면 확인용 데이터는 가명(`홍길동`, `김하늘`)과 가짜 번호로 바꿔 만들고 그 사실을 한 줄로 알린다: "예시 데이터는 가짜 이름으로 넣었어요."
- **로그·에러 리포트·분석 이벤트에 PII를 싣지 않는다** — `console.log(user)`, 에러 메시지에 이메일 포함, 이벤트 속성에 이름 전달 전부 금지.
- **URL·localStorage·쿠키에 PII를 평문으로 저장하지 않는다.** URL 상태는 필터·페이지 같은 화면 상태만 담는다(개인 식별자는 서버 조회로).
- **secret으로 보이는 문자열(API 키·토큰·비밀번호)을 발견하면 값을 출력하지 않는다** — 파일과 줄 번호만 보고한다. `.env*`는 커밋하지 않으며, 무시 설정을 우회해 강제로 담지 않는다.
- **데이터를 한꺼번에 내보내는 작업(전체 목록 CSV·외부 전송·백업)은 사용자 확인 없이 실행하지 않는다.** 무엇을 어디로 보내는지 한 줄로 알리고 승인받는다.
- **위반을 발견하면 멈추고 위치만 보고한다.** "아마 괜찮을 것"이라는 추정으로 진행하지 않는다 — 판단은 사람이 한다.
