Skip to content

보안 표준

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/CDCircleCI Environment Variables / Context
프로덕션환경변수 또는 시크릿 매니저

26.5.3. 시크릿 노출 방지

  • .gitignore.env.local, *.key, *.pem 등을 포함합니다.
  • CI에서 시크릿 스캔 도구(예: git-secrets, gitleaks)를 실행하는 것을 권장합니다.

TIENIPIA QUALIFIED STANDARD