본문으로 건너뛰기

보안

본 문서는 서버가 지키는 보안 규칙을 정의합니다. 인증 계약(토큰 전달 방식과 증명 흐름)은 API 설계가 소유합니다.

1. 인가

인가 원칙은 기본 거부입니다. 전체를 인증 필수로 막고 공개가 필요한 경로만 명시적으로 엽니다.

반대 방향으로 만들면 새 엔드포인트가 기본으로 열린 상태가 되며, 빠뜨린 사실이 사고가 나기 전까지 드러나지 않습니다.

열어 두는 것은 아직 세션이 없는 사용자를 위한 경로뿐이며, 그 보호는 소유 증명과 시도 제한이 담당합니다.

행위자 식별은 전용 계약을 통해 얻습니다. 서비스 계층이 보안 컨텍스트를 직접 조회하지 않습니다. 직접 조회하면 그 서비스의 단위 테스트가 보안 프레임워크를 요구하게 됩니다.

2. 요청이 권한 범위를 정하지 못하게 합니다

접근 범위를 결정하는 값은 인증된 신원에서만 얻습니다.

구분 준수 지침 (Do) 금지 지침 (Don't)
범위 결정 인증 주체에서 범위를 획득합니다 요청 파라미터나 본문에서 받습니다
조건 적용 범위 조건을 필수 조건으로 고정합니다 값이 있을 때만 거는 선택 조건으로 둡니다
소유권 검증 식별자로 진입하는 경로는 조회 전에 그 데이터가 요청자의 것인지 확인합니다 검증 없이 식별자만으로 조회합니다
미소유 응답 미존재로 처리합니다 권한 없음으로 응답합니다. 리소스 존재를 노출합니다

주의

요청이 범위를 결정할 수 있으면 데이터가 샙니다

타인의 식별자를 요청에 넣는 것만으로 그 데이터가 반환됩니다. 요청 값으로 상위 소유자를 역추적하는 형태도 같은 위반입니다. 범위 조건을 선택 조건으로 두면 값이 없을 때 전체가 반환되므로, 조건 누락 시 조회가 실패하는 편이 안전합니다.

3. 입력 검증

모든 요청 DTO를 컨트롤러 진입 시점에 Bean Validation 으로 검증합니다. 검증 메시지는 문자열로 흩지 않고 컨텍스트별 상수로 관리합니다.

파일 업로드는 파일명에서 경로 조작 문자를 제거하고 서버가 생성한 식별자로만 접근하게 합니다.

4. 시크릿

시크릿은 소스와 설정 파일에 평문으로 두지 않고 환경변수로 주입합니다. DB 비밀번호와 OAuth 클라이언트 시크릿, VAPID 키가 그 대상이며, 저장소의 예시 설정에는 값이 아니라 변수 이름만 둡니다.

중요

없으면 안 되는 값에 기본값을 두지 않습니다

기본값이 있으면 주입을 잊었을 때 조용히 약한 값으로 동작합니다. auth.secret 처럼 없으면 안 되는 값이 그 대상입니다. 기동 자체가 실패하는 편이 안전합니다. 자격증명뿐 아니라 콜백 주소처럼 환경마다 달라지는 값도 공통 설정에 기본값을 두지 않습니다.

5. 교차 출처 요청

방어 수단은 배포 구성에 따라 갈립니다.

구성 수단
같은 출처 교차 출처 요청이 발생하지 않으므로 별도 설정을 두지 않습니다
다른 출처 출처 검증과 쿠키 속성으로 막습니다

쿠키 경로의 CSRF 방어는 토큰 왕복 방식 대신 Origin 검증 필터와 SameSite=Lax 쿠키로 합니다. 세션을 서버 렌더 폼 없이 API로만 쓰므로 토큰 왕복이 필요 없습니다.

검사는 상태를 바꾸는 요청 전반에 겁니다. "세션 쿠키가 있을 때만"으로 좁히면 세션 고정 공격이 열립니다. 로그인하지 않은 피해자의 브라우저에 공격자 세션을 심는 교차 출처 요청이 그 조건에 걸리지 않기 때문입니다(검토 #32-2).

배포 구성이 바뀌면 이 전제부터 다시 봅니다.

6. 시도 제한

시도 제한은 여러 축으로 나누어 겁니다. 규칙이 셋입니다.

  • 비대칭 방향을 뒤집지 않습니다. 출발지는 촘촘히, 대상 식별자는 넉넉히 겁니다. 대상별을 조이면 공격자가 남의 식별자로 한도를 소진시켜 정상 이용을 막는 서비스 거부가 됩니다.
  • 제한은 비싼 계산보다 먼저 겁니다. 느린 해시는 의도적으로 느리므로, 검증을 앞에 두면 그 비용 자체가 자원 고갈 수단이 됩니다.
  • 존재 여부를 노출하는 조회보다도 먼저 겁니다. 조회를 앞에 두면 한도를 넘긴 뒤에도 없는 식별자는 미존재 응답으로, 있는 식별자는 한도 초과 응답으로 갈려 거절 자체가 훑기 수단이 됩니다. 이메일로 담당자를 찾는 경로가 여기 해당합니다.

카운터를 메모리에 두면 다중화 시점에 한도가 인스턴스 수만큼 배수가 됩니다. 공유 저장소 어댑터로 교체할 수 있는 형태로 만들고 그 사실을 리스크로 등재합니다.

이 층의 위와 아래에 무엇이 오는지는 결정-0021이 정의합니다. 엣지의 요청률 제한과 사람 증명은 배포 시점에 도입합니다.

7. 클라이언트가 통제하는 값

요청 헤더에서 받아 저장한 뒤 화면에 되돌려 주는 값이 있습니다. 접속 기록의 사용자 에이전트가 대표적입니다.

서버는 이 값을 인증 판단에 쓰지 않고 길이를 자릅니다. 그럼에도 화면이 이스케이프 없이 그리면 자기 화면 한정 스크립트 실행이 됩니다. 계약 문서에 그 값이 원문임을 명시해 소비하는 쪽이 알게 합니다.

8. 검토 절차

보안에 민감한 기능은 병합 전에 보안 검토 페르소나의 검토를 거칩니다. 인증과 세션, 업로드, 프로필이 그 대상입니다.

© 2026 dev.goraebap