보안 표준
26.1. 데이터 암호화
26.1.1. 전송 데이터 (In-Transit)
- 모든 외부 통신은 TLS 1.2 이상을 사용해야 합니다.
- TLS 1.0, 1.1은 사용하지 않습니다.
- 내부 서비스 간 통신도 HTTPS를 사용하는 것을 권장합니다.
26.1.2. 저장 데이터 (At-Rest)
- 데이터베이스에 저장되는 민감 정보(비밀번호, 개인정보)는 반드시 암호화합니다.
- 비밀번호는 BCrypt 알고리즘으로 해시합니다. 평문 저장은 절대 허용하지 않습니다.
java
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}- 기타 민감 데이터는 AES-256 암호화를 적용합니다.
26.1.3. 금지 알고리즘
다음 알고리즘은 보안 취약점이 알려져 있으므로 사용하지 않습니다.
| 금지 알고리즘 | 사유 |
|---|---|
| MD5 | 충돌 공격에 취약 |
| SHA-1 | 충돌 공격에 취약 |
| DES | 키 길이 부족 |
| RC4 | 다수의 취약점 |
26.2. 인증 및 권한
26.2.1. Spring Security 적용
- 모든 백엔드 프로젝트는 Spring Security를 적용해야 합니다.
- SecurityFilterChain을 Bean으로 등록하여 보안 설정을 관리합니다.
java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated())
.build();
}
}26.2.2. RBAC 적용
- 역할 기반 접근 제어(RBAC)를 적용해야 합니다.
- 최소 권한 원칙을 따릅니다. 사용자에게 필요한 최소한의 권한만 부여합니다.
26.2.3. 세션 관리
- REST API는 Stateless 방식을 사용합니다. 서버 측 세션을 사용하지 않습니다.
- 인증 토큰(JWT 등)은 적절한 만료 시간을 설정합니다.
26.3. 입력 검증
26.3.1. Bean Validation
모든 API 요청 DTO에 Bean Validation 어노테이션을 적용합니다.
java
public record CreateUserRequest(
@NotBlank(message = "이름은 필수입니다.")
@Size(max = 50, message = "이름은 50자 이내여야 합니다.")
String name,
@NotBlank(message = "이메일은 필수입니다.")
@Email(message = "올바른 이메일 형식이 아닙니다.")
String email,
@NotBlank(message = "비밀번호는 필수입니다.")
@Size(min = 8, max = 100, message = "비밀번호는 8자 이상 100자 이하여야 합니다.")
String password
) {}Controller에서 @Valid를 사용하여 검증을 트리거합니다.
java
@PostMapping("/users")
public ResponseEntity<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) {
return ResponseEntity.status(HttpStatus.CREATED)
.body(userService.createUser(request));
}26.3.2. XSS 방어
- 사용자 입력을 HTML에 렌더링할 때는 반드시 이스케이프 처리합니다.
- Vue.js의 이중 중괄호(
)는 기본적으로 이스케이프를 수행합니다. v-html사용은 금지합니다. 불가피한 경우 DOMPurify 등의 라이브러리로 정화합니다.
26.3.3. SQL Injection 방어
- jOOQ의 타입 안전 DSL API를 사용하여 파라미터 바인딩을 자동으로 적용합니다.
- jOOQ DSL을 통해 작성된 쿼리는 자동으로 prepared statement로 변환되어 SQL Injection을 방지합니다.
- 문자열 기반 raw SQL은 사용하지 않습니다.
java
// 잘못된 예 (문자열 결합 — SQL Injection 위험)
dsl.execute("SELECT * FROM users WHERE name = '" + name + "'");
// 올바른 예 (jOOQ DSL — 자동 파라미터 바인딩)
dsl.selectFrom(USERS)
.where(USERS.NAME.eq(name))
.fetch();26.4. 의존성 보안
26.4.1. 도구 적용
- OWASP Dependency-Check를 Maven 플러그인으로 적용합니다. (Maven 빌드 설정 문서 참고)
- CVSS 점수 7 이상의 취약점이 발견되면 빌드를 실패시킵니다.
- 보안 스캔은 CI 파이프라인에서 주기적으로 실행합니다.
26.4.2. 의존성 업데이트 정책
- 보안 취약점이 발견된 의존성은 7일 이내에 패치 버전으로 업데이트합니다.
- 정기적으로(최소 월 1회) 의존성 버전을 점검합니다.
26.5. 시크릿 관리
26.5.1. 금지 사항
- 소스코드에 비밀번호, API 키, 토큰 등을 절대 하드코딩하지 않습니다.
- Git 이력에 시크릿이 포함된 경우, 해당 시크릿을 즉시 폐기하고 재발급합니다.
26.5.2. 관리 방법
| 환경 | 관리 방법 |
|---|---|
| 로컬 개발 | .env.local 파일 (Git 미추적) |
| CI/CD | CircleCI Environment Variables / Context |
| 프로덕션 | 환경변수 또는 시크릿 매니저 |
26.5.3. 시크릿 노출 방지
.gitignore에.env.local,*.key,*.pem등을 포함합니다.- CI에서 시크릿 스캔 도구(예: git-secrets, gitleaks)를 실행하는 것을 권장합니다.