관리자가 회사 사이트에 로그인한 채 다른 웹페이지를 열었습니다. 그 페이지가 관리자 설정 변경 주소로 요청을 만들 수 있다면 어떻게 될까요? 브라우저는 조건에 따라 로그인 쿠키를 자동으로 붙일 수 있습니다. 서버가 ‘쿠키가 있으니 관리자가 직접 누른 것’이라고 생각하면 외부 페이지가 관리자의 권한을 빌려 상태를 바꾸는 CSRF(교차 사이트 요청 위조)가 발생합니다. 스팸 방어나 로그인 보안과는 다른 문제입니다. 관리자 기능에는 사용자의 의도를 확인하는 별도 경계가 필요합니다.
읽기 요청으로 데이터를 바꾸지 않는다
관리자 화면에서 링크를 여는 GET 요청만으로 글을 삭제하거나 사용자 권한을 바꾸면 위험합니다. 브라우저의 미리보기, 검색 로봇, 외부 링크만으로도 상태 변경이 실행될 수 있기 때문입니다. 생성·수정·삭제·발행·메일 발송은 의미에 맞는 상태 변경 메서드로 처리하고 서버에서 방어 검사를 적용합니다. ‘삭제 확인’ 화면을 GET으로 보여 주는 것은 가능하지만 실제 삭제는 별도 보호된 요청에서만 실행해야 합니다. 테스트는 관리자 페이지의 버튼뿐 아니라 API와 오래된 URL까지 포함해야 합니다.
대표적인 방어는 서버가 발급한 예측 불가능한 CSRF 토큰을 폼이나 요청 헤더에 담고, 제출할 때 세션과 일치하는지 검증하는 방식입니다. 토큰이 없거나 틀리면 서버가 작업을 거부해야 합니다. 토큰을 URL에 넣으면 방문 기록이나 로그에 남을 수 있으므로 피합니다. AJAX 요청은 공통 요청 함수가 토큰을 헤더로 보내게 만들되, 토큰을 얻는 경로 역시 현재 사용자에게만 허용해야 합니다. OWASP의 CSRF 방어 지침은 토큰 방식과 출처 검사, 쿠키 정책의 역할을 구분해 설명합니다.

SameSite와 Origin은 중요한 보조 경계다
쿠키의 SameSite 속성은 외부 사이트에서 들어오는 요청에 쿠키를 어느 범위까지 붙일지 조절합니다. 하지만 같은 사이트의 다른 서브도메인이나 상태를 바꾸는 GET 같은 문제까지 항상 해결해 주지는 않습니다. 그래서 대부분의 관리자 기능에서는 토큰 검사를 중심에 두고 SameSite를 방어 계층으로 사용합니다. Origin이나 Referer도 요청 출처를 확인하는 데 도움이 됩니다. 문자열의 일부가 도메인과 같다는 이유만으로 허용하지 말고 정확한 출처를 비교해야 합니다. 헤더가 없거나 null인 경우를 무조건 신뢰하는 예외 규칙도 위험합니다.
CSRF와 XSS는 별개지만 연결됩니다. 공격자가 우리 사이트 안에서 스크립트를 실행할 수 있다면 페이지의 토큰을 읽거나 정상 요청을 만들 수 있습니다. 그러므로 CSRF 토큰을 붙였다고 HTML 입력 살균과 콘텐츠 보안 정책, 권한 검증을 생략할 수 없습니다. 반대로 CORS를 제한했다는 이유만으로 모든 CSRF가 막히는 것도 아닙니다. 브라우저가 요청을 보내는 것과 응답을 외부 페이지에서 읽을 수 있는 것은 다른 문제이기 때문입니다. 민감한 관리 기능에는 재인증이나 명시적 확인을 추가하되, 확인 창만을 유일한 방어로 삼지 않습니다.
같은 관리자 화면이라도 발행, 사용자 초대, 설정 변경, 대량 삭제의 위험은 다릅니다. 모든 동작에 기본 CSRF 방어를 적용한 뒤 영향이 큰 작업에는 대상과 범위를 다시 보여 주고 확인을 요구할 수 있습니다. 여러 탭을 열어 작업하는 관리자에게 과도하게 짧은 토큰 수명을 적용하면 정상 작업 실패가 잦아지므로 보안 정책과 업무 흐름을 함께 시험해야 합니다. 실패를 우회 허용으로 처리하지 않는 것이 중요합니다.

실패 시 안전하게 거부하는지 확인한다
로그인한 상태에서 토큰 없는 폼 제출, 틀린 토큰, 다른 출처의 요청, 오래 열린 탭의 토큰 만료, 복수 브라우저 탭을 시험합니다. 토큰이 만료됐을 때는 작업을 실행하지 않고 입력 내용을 잃지 않도록 다시 시도할 방법을 안내합니다. 정상 사용자 경험 때문에 검사를 느슨하게 만드는 대신 토큰 갱신과 오류 처리를 설계해야 합니다. 보안 로그에는 거부된 요청의 경로와 이유를 기록하되 비밀 토큰 자체를 남기지 않습니다. 관리자 페이지의 보안은 ‘로그인했는가’에서 끝나지 않습니다. 로그인된 브라우저가 보낸 요청이 실제로 그 사용자의 의도인가를 상태 변경마다 확인해야 합니다.