# HMM 포털 HttpOnly 쿠키 인증 적용·검증 보고서 - 일자: 2026-07-23 - Redmine: #709 - 브랜치: `hmm-backoffice` - 서비스: `https://hmm.cloud-handson.com` ## 수정 결과 Streamlit의 `poc4_remember` query-token 생성·복원 코드를 삭제했다. Nginx가 모든 포털 HTTP·WebSocket 요청에 `auth_request`를 수행하고, localhost 인증 서비스가 검증한 사용자와 만료 시각만 Streamlit에 전달한다. | 구성 | 결과 | |---|---| | 인증 서비스 | `hmm-portal-auth.service` / active | | 인증 서비스 bind | `127.0.0.1:8621` | | 포털 | `poc4-streamlit.service` / active | | 공개 경계 | Nginx `auth_request` | | session cookie | `__Host-HMM_PORTAL_SESSION` | | cookie 속성 | `Secure; HttpOnly; SameSite=Lax; Path=/` | | 로그인 CSRF | 10분 일회용 double-submit cookie | | URL token | 제거 | | 이전 서명키 | 운영 환경과 환경 백업에서 제거 | ## 자동 테스트 ```text python3 -m unittest discover -s tests -p 'test_*.py' -v Ran 21 tests OK (skipped=1) ``` 검증 항목: - PBKDF2 비밀번호 비교 - session token 발급·검증·만료·조작 거부 - persistent/session/logout cookie 속성 - login rate limit - 실제 HTTP login → auth check → tamper reject → logout 흐름 - login 성공 redirect가 `/`이고 token·remember query가 없는지 확인 ## 운영 HTTP 검증 | 요청 | 결과 | |---|---| | 쿠키 없이 `/` | 302 → `/auth/login` | | `/?poc4_remember=retired-token` | 302 → `/auth/login`, query 전달 안 됨 | | `/auth/login` | 200, `Cache-Control: no-store` | | 조작 session cookie | 401 | | 유효 session cookie | Streamlit 200 | | `/auth/logout` | session cookie `Max-Age=0`, 로그인 화면 이동 | 로그인 페이지 응답에는 `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy: no-referrer`, 제한된 CSP가 포함된다. ## 실제 브라우저 검증 Playwright에서 다음을 확인했다. - 미인증 query-token URL은 `/auth/login`으로 이동하고 최종 URL에서 query가 사라짐 - 로그인 화면의 사용자 ID, 비밀번호, 로그인 유지 UI 표시 - 인증 후 최종 URL은 `/`, query 없음 - `__Host-HMM_PORTAL_SESSION`: HttpOnly=true, Secure=true, SameSite=Lax, Path=/ - `document.cookie`에 portal session cookie가 없음 - 아키텍처·시나리오·감사로그·보안관리 탭 필수 내용 표시 - `https://hmm-mcp.cloud-handson.com/mcp` 설정 표시 - 로그아웃 후 session cookie 없음 - page error 0, console error 0 캡처와 기계 판독 보고서는 운영 검증 작업 디렉터리 `/private/tmp/hmm-cookie-auth-audit/`에 생성했다. ## 보안 정리 - 노출된 과거 query-token은 새 인증 경로에서 사용되지 않으며 기존 HMAC 서명키도 회전했다. - 회전 전 환경 백업 두 개에서는 이전·중간 서명키 줄을 제거했다. - 현재 secret은 `/opt/hmm-poc4/.env`에만 있고 파일 권한은 `opc:opc 0600`이다. - 토큰, 비밀번호, cookie 값은 Git·Redmine·보고서·서비스 로그에 기록하지 않았다. - Nginx access log에는 앞으로 인증 token이 URL로 들어오지 않는다.