토스페이먼츠에서 웹 취약점을 진단했다. 그전에는 BoB와 대회들에서, 남이 만든 것의 빈틈을 찾는 일을 했다. 지금은 반대편에 서서 화면을 만든다.
방향은 바뀌었는데, 쓰는 근육은 놀랍게도 거의 같다.
보안은 "신뢰 경계"를 묻는 일이다
취약점 진단의 첫 질문은 늘 하나였다. 이 데이터는 어디서 왔는가.
사용자가 보낸 값인가, 서버가 만든 값인가. 이 경계를 흐리게 그린 곳에서 사고가 난다. XSS도 SQL 인젝션도 결국 "믿으면 안 되는 것을 믿었다"는 한 문장으로 요약된다.
프론트엔드에서도 질문은 똑같다.
- 이 상태의 주인은 누구인가
- 이 값은 서버가 준 것인가, 클라이언트가 만든 것인가
- 이 둘이 어긋나면 화면은 뭘 보여줘야 하는가
경계를 명확히 그은 코드는 안전하기만 한 게 아니라 읽기 쉽다. 상태 관리 설계와 보안 모델링은 같은 그림을 다른 이름으로 그리는 일이었다.
공격자는 해피 패스를 걷지 않는다
취약점을 찾을 때 정상 흐름은 3분이면 끝난다. 나머지 시간은 전부 이상한 짓을 하는 데 쓴다. 순서를 바꾸고, 두 번 누르고, 중간에 끊고, 없는 값을 넣는다.
UI를 만들 때도 똑같이 한다.
// 해피 패스만 있는 코드
const { data } = useQuery(...);
return <Chart data={data} />;
이 코드가 답하지 않는 질문들이 있다. 로딩 중에는? 실패하면? 데이터가 빈 배열이면? 요청이 끝나기 전에 사용자가 떠나면? 같은 버튼을 두 번 누르면?
버그 리포트의 대부분은 여기서 나온다. 기능이 없어서가 아니라, 없다고 가정한 상태가 실제로 존재해서 난다.
그래서 지금 하는 일
경계를 긋고, 이상한 입력을 먼저 상상하고, 숫자로 확인한다. 프레임을 재고 병목을 찾는 일도 결국 같은 태도다 — 짐작하지 않고 증거를 만든다.
보안에서 배운 건 도구가 아니라 기본값을 의심하는 자세였다. 그게 지금 화면을 만드는 데도 제일 쓸모 있다.