포트폴리오에서 비공개 저장소 링크 노출 차단
목차
비공개 저장소 링크 제거하다 발견한 권한 누수
포트폴리오 페이지에 프로젝트 리스트 뿌리는데, 비공개 레포까지 그냥 클릭 가능한 링크로 박혀있던 걸 뒤늦게 발견함. 외부에서 클릭하면 404로 튕기긴 하지만, 그 자체로 "여기 비공개 레포 있음"을 노출하는 거라 좋은 그림은 아님.
뭐가 문제였는지
- 카드 컴포넌트에서
repo.url을 무조건 앵커 태그로 감쌌음 isPrivate플래그는 데이터에 있었지만 렌더링 분기를 안 탔음- 결과적으로 외부 노출용 페이지에 내부 레포 이름 + 깨진 링크가 같이 노출됨
내부에서만 보던 시절엔 문제 안 됐는데, 이커머스 파트너 쪽에 공유하는 외부 페이지로 용도가 확장되면서 드러남. 권한 분기 빠진 UI 컴포넌트의 전형적인 케이스.
고친 방식
분기 단순하게 가져감. 비공개면 링크 빼고 자물쇠 아이콘 + "Private" 라벨로 표시함.
{repo.isPrivate ? (
<span className="repo-card locked" role="text">
<LockIcon /> {repo.name}
<em>Private</em>
</span>
) : (
<a href={repo.url} className="repo-card">
{repo.name}
</a>
)}
자물쇠 아이콘은 디자인 시스템에 이미 있던 거 그대로 가져다 씀. 새로 그릴 필요 없었음.
디테일에서 막힌 부분
| 이슈 | 원인 | 처리 |
|---|---|---|
| 호버 커서가 여전히 pointer | 공통 스타일 상속 | locked 변형에 cursor: default |
| 스크린리더가 "링크"로 읽음 | 앵커 태그 잔존 | role="text" 로 교체 |
| 자물쇠 색이 본문과 동일 | 토큰 미지정 | muted 색상 토큰 적용 |
호버 커서랑 접근성 부분은 처음 PR 올렸을 때 리뷰에서 잡혀서 한 번 더 돌렸음. UI 분기 한 줄 같아 보여도 디자인 토큰/접근성/시멘틱까지 같이 봐야 한다는 거 다시 확인함.
회고
- 데이터에 권한 플래그가 있다고 끝이 아님. 렌더링 레이어에서 분기를 실제로 타는지 까지 확인해야 함
- 내부 전용 컴포넌트가 외부 노출 경로에 그대로 흘러가는 케이스는 항상 의심
- 자물쇠 아이콘 같은 시각적 신호는 "여기 못 봄"을 명시적으로 알려줘서 오히려 어색하지 않음. 숨기는 것보다 표시하는 게 나을 때도 있음
다음
댓글 0
첫 댓글 달아줘.