이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
- 개인 프로젝트에서도 반드시 지켜야 하는 보안 기본선은 무엇인가?
- 기업 환경에서는 어떤 운영, 감사, 승인 기준이 추가되는가?
- 작은 서비스에서 시작한 보안 설계를 성장 가능한 구조로 만들려면 무엇을 남겨야 하는가?
개요
개인 프로젝트와 기업 보안의 차이는 “개인은 간단히 처리해도 된다”가 아니다. 차이는 보호해야 할 자산의 규모, 영향 범위, 감사 요구, 운영 인력, 사고 대응 책임에서 나온다. 작은 서비스에서도 비밀번호 원문 저장, HTTPS 미사용, 권한 테스트 부재, 민감 로그 노출은 허용할 수 없다.
개인 프로젝트에서 현실적으로 모든 기업 장비와 프로세스를 갖추기는 어렵다. 그러나 기본선은 있어야 한다. 기업 수준은 이 기본선 위에 승인 흐름, 접근 통제, 중앙 로그, 탐지 규칙, 사고 대응, 보존 정책이 추가된다.
이 문서는 학습자가 “지금 당장 해야 할 것”과 “운영 규모가 커지면 추가해야 할 것”을 구분하게 만드는 지도다.
공격 시나리오
작은 서비스는 보안 장치가 없어서 공격이 쉬운 경우가 많다.
- 로그인 API에 rate limit가 없어 credential stuffing이 가능하다.
- 비밀번호는 빠른 해시나 원문으로 저장된다.
- 관리자 기능은 URL만 알면 접근 가능하거나 프론트 버튼 숨김에 의존한다.
- 로그에는 token, 이메일, 전화번호, 전체 카드번호가 섞인다.
- 사고가 난 뒤 어떤 계정이 영향을 받았는지 확인할 감사 로그가 없다.
기업 환경에서도 사고는 난다. 다만 기업은 피해 범위를 줄이고, 누가 무엇을 했는지 복원하며, 재발 방지를 추적할 장치를 요구한다.
취약한 요청/응답 예시
POST /admin/users/1004/role HTTP/1.1
Host: toy.example.com
Cookie: SESSION=member-session
Content-Type: application/json
{"role":"ADMIN"}HTTP/1.1 200 OK
Content-Type: application/json
{"id":1004,"role":"ADMIN"}작은 프로젝트에서 “관리자 페이지 링크를 숨겼으니 괜찮다”고 생각하면 이런 요청이 그대로 성공한다. 기업 환경이라면 관리자 권한, 승인, 감사 로그, 변경 사유가 모두 필요하다.
주제별 핵심 판단
- 개인 프로젝트도 비밀번호 해시, HTTPS, 안전한 쿠키, 권한 테스트, 민감 로그 마스킹은 기본선이다.
- 기업 수준은 정책 문서보다 변경 이력, 승인 흐름, 탐지와 대응 시간이 중요해진다.
- 작은 서비스라도 audit log와 계정 잠금 기준이 없으면 사고를 복원하기 어렵다.
- 성장 가능한 보안은 나중에 붙이는 장식이 아니라 처음부터 경계를 분리한 구조다.
- 보안 수준은 “도구 유무”보다 “사고가 났을 때 설명 가능한가”로 평가한다.
수준 비교
| 항목 | 개인 프로젝트 기본선 | 기업 운영 수준 |
|---|---|---|
| 인증 | 비밀번호 해시, HTTPS, 로그인 실패 제한 | MFA, 위험 기반 인증, 계정 잠금 정책 |
| 인가 | 서버 권한 검사, 소유자 조건 테스트 | RBAC/ABAC, 승인 흐름, 권한 변경 감사 |
| 브라우저 | HttpOnly Secure SameSite, 기본 CSRF | CSP 운영, Origin allowlist, 위반 리포트 |
| API 입력 | DTO allowlist, Bean Validation | 보안 테스트 자동화, abuse 탐지 |
| 로그 | 민감값 마스킹, traceId | 중앙 로그, 보존 정책, SIEM 연동 |
| 사고 대응 | 세션 무효화와 공지 기준 | playbook, 담당자, 증거 보존, 재발 추적 |
개선된 요청/응답 예시
POST /admin/users/1004/role-change-requests HTTP/1.1
Host: api.example.com
Authorization: Bearer admin-token
Content-Type: application/json
X-Request-Id: 8c12
{
"role": "SUPPORT_ADMIN",
"reason": "temporary customer support",
"expiresAt": "2026-07-07T00:00:00Z"
}HTTP/1.1 202 Accepted
Content-Type: application/json
{"requestId":"role-change-7781","status":"PENDING_APPROVAL"}권한 변경은 즉시 반영보다 승인 가능한 요청으로 분리하는 편이 안전하다. 작은 서비스에서는 승인 workflow까지 없더라도 변경 사유와 감사 로그는 남겨야 한다.
방어 설계
- 처음부터 일반 사용자 API와 관리자 API를 분리한다.
- 비밀번호 저장은 느린 단방향 해시를 사용한다.
- 쿠키에는 HttpOnly, Secure, SameSite를 명시한다.
- 권한 변경, 이메일 변경, 비밀번호 변경, 결제는 감사 이벤트로 남긴다.
- secret은 git, 이미지, 로그에 남기지 않는다.
- 운영자가 세션 무효화, token 폐기, 권한 회수를 할 수 있게 만든다.
- 개인 프로젝트라도 보안 체크리스트를 README나 운영 문서에 남긴다.
- 기업 수준에서는 승인자, 변경 사유, 만료 시간, 보존 기간, 탐지 규칙을 추가한다.
Spring/HTTP 예시
@PreAuthorize("hasAuthority('user.role.change.request')")
@PostMapping("/admin/users/{userId}/role-change-requests")
public RoleChangeRequestResponse requestRoleChange(@PathVariable Long userId,
@Valid @RequestBody RoleChangeCommand command,
Authentication authentication) {
Long requesterId = ((CustomPrincipal) authentication.getPrincipal()).memberId();
return roleChangeService.request(userId, requesterId, command);
}관리자 권한 변경도 바로 DB update로 끝내지 않는다. 누가 요청했고, 어떤 권한을, 왜, 언제까지 부여하려는지 기록하면 개인 프로젝트에서도 기업식 감사 구조로 확장할 수 있다.
운영 로그와 감사 지점
level=INFO event=role_change_requested actor=admin:12 target=member:1004 role=SUPPORT_ADMIN expiresAt=2026-07-07 reason=temporary_customer_support traceId=8c12
level=INFO event=role_change_approved approver=security:3 requestId=role-change-7781 result=applied traceId=8c12감사 로그는 관리자도 추적 대상이라는 전제를 가진다. 운영자 행위가 더 강한 권한을 가지므로 더 강한 기록이 필요하다.
- 관리자 로그인과 권한 변경은 일반 로그인보다 오래 보존한다.
- 민감 데이터 조회에는 조회 사유를 남긴다.
- 로그에는 개인정보 원문 대신 식별 가능한 내부 id와 traceId를 남긴다.
- 보안 이벤트는 삭제 권한을 제한하고 별도 저장소를 검토한다.
- 탐지 규칙은 권한 변경 직후 대량 조회 같은 연쇄 이벤트를 볼 수 있어야 한다.
실전 판단 기준
- 개인 프로젝트에서도 비밀번호 해시와 권한 테스트는 생략하지 않는다.
- 로그에 token 원문과 비밀번호가 찍히지 않는지 직접 확인한다.
- “지금은 작다”는 이유로 신뢰 경계와 권한 경계를 섞지 않는다.
- 나중에 승인, 감사, 탐지를 붙일 수 있도록 이벤트와 권한 모델을 분리한다.
- 좋은 판단은 비용을 고려하되 사고 때 설명 가능한 최소 장치를 남기는 것이다.
테스트 포인트
- 일반 사용자가 관리자 API를 직접 호출했을 때 거부되는지 확인한다.
- 권한 변경 요청과 실제 적용 이벤트가 모두 감사 로그에 남는지 확인한다.
- 비밀번호 해시 알고리즘과 cost가 운영 가능한 수준인지 확인한다.
- 로그에 token, 비밀번호, 전체 개인정보가 남지 않는지 샘플 로그로 확인한다.
- 권한 변경 후 기존 세션과 token에 새 권한이 어떻게 반영되는지 테스트한다.
위험 신호!
- “개인 프로젝트라서 괜찮다”며 비밀번호를 원문 또는 빠른 해시로 저장한다.
- 관리자 페이지 링크를 숨기는 것으로 권한 통제를 대신한다.
- 운영자가 사용자 데이터를 조회해도 감사 로그가 없다.
- 권한 변경에 사유, 승인자, 만료 시간이 없다.
- 사고가 나도 영향 계정 목록을 뽑을 로그가 없다.
확인 질문
확인 질문
- 개인 프로젝트에서도 생략하면 안 되는 보안 기본선은 무엇인가?
- HTTPS, 비밀번호 해시, 안전한 쿠키, 서버 권한 검사, 민감 로그 마스킹, 기본 감사 로그다.
- 기업 수준 보안에서 추가되는 핵심은 무엇인가?
- 승인 흐름, 중앙 감사 로그, 탐지 규칙, 보존 정책, 사고 대응 책임이다.
- 작은 서비스가 성장 가능한 보안을 가지려면 무엇을 남겨야 하는가?
- actor, resource, action, result, reason을 가진 보안 이벤트와 분리된 권한 모델을 남겨야 한다.