취약점 유형❗ 인증 우회 (Authentication Bypass)
설명: 인증 없이 보호된 API에 접근하는 공격
방어전략:
✅ Spring Security에서 .anyRequest().authenticated() 설정
✅ @AuthenticationPrincipal로 로그인 사용자 정보 검증
✅ 인증 예외 경로(/login, /signup)만 .permitAll() 처리
취약점 유형❗ 권한 우회 (Authorization Bypass)
설명: 일반 사용자가 관리자 기능 또는 다른 유저 데이터 접근
방어전략:
✅ @PreAuthorize("hasRole('ADMIN')") 또는 @Secured("ROLE_ADMIN")
✅ 사용자 리소스 접근 시 if (userId != principalId) 검증
✅ 모든 민감 API에 Role 기반 인가 적용
취약점 유형❗ SQL Injection
설명: 입력값을 통해 쿼리 조작
방어전략:
✅ JPA / QueryDSL 사용 → 자동 바인딩
✅ NativeQuery 시에도 ? 파라미터 바인딩
❌ 문자열 연결로 SQL 만들지 않기
취약점 유형❗ 파일 업로드 경로 조작 (Directory Traversal)
설명: ../../etc/passwd 같은 경로 조작으로 시스템 파일 접근 시도
방어전략:
✅ Paths.get(...).normalize() 사용
✅ 기준 루트 밖으로 벗어나면 차단
✅ 허용 확장자 필터링 + 크기 제한
취약점 유형❗ CSRF 공격
설명: 로그인된 상태에서 외부 사이트가 의도치 않은 요청을 전송
방어전략:
✅ SameSite=Strict 쿠키 설정
✅ REST API에서는 csrf().disable() + JWT 사용
✅ POST 요청만 허용 + Origin 헤더 확인 (선택)
취약점 유형❗ 민감 정보 응답 포함
설명: 비밀번호, 토큰, 내부 에러 등이 응답으로 전달
방어전략:
✅ UserResponseDTO 같은 전용 DTO 사용
✅ @JsonIgnore, @JsonView 등으로 민감 필드 숨김
✅ 전역 예외 처리(@ControllerAdvice)로 오류 메시지 통제
취약점 유형❗ 비밀번호 평문 저장
설명: 암호화 없이 DB에 저장된 비밀번호 → 유출 시 큰 피해
방어전략:
✅ BCryptPasswordEncoder로 해싱 저장
✅ 로그인 시에도 passwordEncoder.matches() 비교
✅ 비밀번호 길이 + 복잡도 정책 설정
취약점 유형❗ JWT 위조 / 검증 생략
설명: 공격자가 직접 만든 가짜 JWT를 서버가 받아들이는 경우
방어전략:
✅ JWT 서명 검증 필수 (secret key로 verify)
✅ 토큰 만료시간(exp) 확인
✅ Redis 등으로 refreshToken 상태 관리
취약점 유형❗ 잘못된 CORS 설정
설명: 외부에서 민감 요청 허용 → Authorization 헤더, 쿠키 노출
방어전략:
✅ allowedOrigins는 신뢰 가능한 도메인만
✅ allowCredentials(true) 설정 시 * 사용 ❌
✅ Preflight 요청 허용 정확히 설정
취약점 유형❗ 로그에 민감 정보 출력
설명: 서버 로그에 token, password 등 출력되면 보안사고로 이어질 수 있음
방어전략:
✅ log.info(user) 대신 필요한 필드만 출력
✅ production 환경에서는 로그 레벨 최소화
✅ 요청/응답 필터로 로깅 범위 제한 가능
취약점 유형❗ 의존성 보안 취약점
설명: 사용 중인 라이브러리 내 취약점을 통한 공격 가능성
방어전략:
✅ OWASP Dependency Check, Snyk, npm audit 등 정기 실행
✅ Spring Boot 공식 BOM 기반 의존성 사용
✅ 버전 주기적 점검 및 알림 설정
취약점 유형❗ Rate Limit 미적용
설명: 무한 로그인 시도, 댓글 폭탄 등 DoS 취약
방어전략:
✅ 사용자/IP 기반 요청 제한 필터 적용
✅ 로그인 시도 횟수 제한 + CAPTCHA 도입
✅ nginx or API Gateway에서 IP 단위 제한
Spring Boot 개발 시 보안 좋은 습관
- 인증 우회 방지를 위해 모든 요청은 인증 필터 통과하도록 구성
- 민감 데이터는 DTO로 선별적으로 제공 (절대 Entity 반환 금지)
- 토큰/비밀번호/기밀정보는 환경변수로 관리 (application.yml에 노출 X)
- 의존성 추가 시 GitHub Advisory / CVE 체크 후 사용
- Spring Security 테스트(@WithMockUser)로 권한 테스트 병행
- 프론트엔드와의 연결 시 CORS 정확히 설정
위험한 코드 vs 안전한 코드
❌ 위험한 코드 (Native Query에서 문자열 조합)
String sql = "SELECT * FROM users WHERE username = '" + username + "'";
✅ 안전한 코드 (JPA 또는 바인딩 처리)
@Query("SELECT u FROM User u WHERE u.username = :username")
User findByUsername(@Param("username") String username);
Spring Boot 보안 마인드셋
백엔드는 "절대 믿을 수 없는 사용자"와 "무조건 공격당할 수 있다"는 가정에서 설계.
- 요청은 항상 악의적일 수 있다고 가정하고 검증
- 인증은 로그인 여부, 인가는 역할/소유자 확인
- 모든 입력은 검증, 모든 출력은 제한
- 보안은 개발의 시작이자 유지보수의 끝까지 고려해야 함
'Computer > Computer Security' 카테고리의 다른 글
보안 시스템 I (0) | 2025.04.01 |
---|---|
배포 환경 보안 체크리스트 (0) | 2025.04.01 |
React 보안 체크리스트 (0) | 2025.04.01 |
웹 개발자, 특히 풀스택 개발자라면 반드시 알고 있어야 할 사이버 공격 종류 (2) | 2025.04.01 |
네트워크 보안 (0) | 2025.03.28 |