Technote

보안 실무

연재 REST API 와 헤드리스 8부 중 4부

인증 고르기 — 쿠키 · 애플리케이션 비밀번호 · 토큰

세 가지 방식은 편의의 차이가 아니라 위협 모델의 차이입니다. 브라우저에서 부르는가, 서버가 부르는가, 제3자가 발급하는가에 따라 답이 정해집니다.

REST 라우트를 만들고 나면 “누가 부르는가” 를 정해야 합니다. 워드프레스에서 실질적인 선택지는 셋이고, 셋은 편의의 차이가 아니라 지켜야 할 비밀이 어디에 놓이는가의 차이입니다.

세 가지 인증 — 호출자가 누구인지가 방식을 정한다

쿠키와 nonce — 브라우저가 부를 때

로그인한 사용자의 브라우저에서 같은 사이트의 API 를 부를 때 쓰는 방식입니다. 인증은 쿠키가 하고, nonce 는 인증이 아니라 CSRF 방어입니다. 둘의 역할을 섞으면 판단이 어긋납니다 — nonce 는 비밀이 아니고, 페이지 소스에 그대로 실려도 되는 값입니다.

wp_enqueue_script( 'wper-app', $url, [], $ver, true );

wp_localize_script(
	'wper-app',
	'wperApi',
	[
		'root'  => esc_url_raw( rest_url( 'wper/v1/' ) ),
		'nonce' => wp_create_nonce( 'wp_rest' ),
	]
);

// 클라이언트: fetch( wperApi.root + 'orders/12', {
//   credentials: 'same-origin',
//   headers: { 'X-WP-Nonce': wperApi.nonce }
// } )

이 방식의 함정은 nonce 가 만료된다는 것입니다. 하루쯤 열어 둔 탭에서 저장을 누르면 rest_cookie_invalid_nonce 로 403 이 돌아옵니다. 사용자 입장에서는 “방금까지 되던 것이 안 된다” 이므로, 클라이언트가 이 오류를 잡아 새로고침을 안내하거나 하트비트로 nonce 를 갱신해야 합니다.

위협 모델은 명확합니다. 비밀이 브라우저 세션이므로 XSS 가 성립하면 그대로 끝입니다. 그래서 이 방식을 쓰는 화면일수록 출력 이스케이프가 중요해집니다.

애플리케이션 비밀번호 — 서버가 부를 때

다른 서버나 스크립트가 우리 API 를 부를 때는 쿠키가 없습니다. 코어의 애플리케이션 비밀번호가 이 자리를 위해 있습니다. 사용자 프로필에서 용도별로 발급하고, HTTP Basic 으로 보내며, 개별로 폐기할 수 있습니다.

curl -u 'ci-bot:abcd EFGH ijkl MNOP qrst UVWX' 
     https://example.com/wp-json/wp/v2/posts?status=draft

중요한 성질이 셋 있습니다. 첫째, 사용자의 권한을 넘지 못합니다 — 그러니 자동화 전용 사용자를 만들고 필요한 최소 역할만 줍니다. 둘째, 비밀번호 자체와 분리돼 있어 유출 시 그 하나만 폐기하면 됩니다. 셋째, HTTPS 가 전제입니다. Basic 인증은 자격증명을 헤더에 그대로 싣습니다.

위협 모델은 “설정 파일에 오래 살아 있는 자격증명” 입니다. 저장소에 커밋되지 않게 하고, 회전 절차를 미리 정해 두는 것이 이 방식의 숙제입니다.

토큰 — 제3자가 발급할 때

모바일 앱이나 별도 프런트엔드가 자기 사용자를 대신해 부르는 경우, 또는 만료가 짧은 자격증명이 필요한 경우에 토큰을 씁니다. 코어 기능이 아니므로 플러그인이나 자체 구현이 붙고, 그 순간 발급자와 갱신 흐름을 우리가 운영하게 됩니다.

여기서 정직할 필요가 있습니다. 토큰이 더 현대적이라서 더 안전한 것이 아닙니다. 짧은 만료는 유출의 창을 줄여 주지만, 대신 갱신 토큰 보관 · 폐기 목록 · 키 회전이라는 새 운영 부담이 생깁니다. 서버 하나가 야간 배치로 글을 올리는 정도라면 애플리케이션 비밀번호가 정답이고, 토큰은 과합니다.

호출자별 선택 — 마지막 두 줄은 다른 답을 요구한다

보안 설정 전반의 관점은 보안 아카이브에 있고, 인증 · 권한 구성을 포함한 점검을 한 번에 받고 싶다면 최적화 지원 사업에 진단이 포함돼 있습니다.

다음 회차

위 그림의 네 번째 줄이 다음 회차입니다. 외부 서비스가 우리를 부르는 웹훅에는 쿠키도 nonce 도 없어서, nonce 검증을 걸면 100% 실패합니다. 그럼 무엇으로 검증하는지 다룹니다.

이 주제의 다른 글

노하우 목록으로

보안 실무

업로드 디렉터리의 PHP 실행 차단 — 마지막 관문

업로드 취약점은 파일을 올리는 데서 끝나지 않습니다. 올라간 파일이 실행될 때 원격 코드 실행이 됩니다. uploads 에서 PHP 를 못 돌게 하면 그 승격이 끊깁니다.

운영 · 관리자 2분 읽기

보안 입문

DISALLOW_FILE_EDIT 하나로 막히는 공격 경로

관리자 비밀번호가 한 번 새면, 내장 테마 편집기는 웹셸 설치 화면이 됩니다. 상수 한 줄이 그 최단 경로를 지웁니다.

개발자 · 운영 · 관리자 2분 읽기

₩270,000 · 신청하기