[스프링부트] 익명 블로그 V5 - 인증 블로그 V1 - 스프링 시큐리티(Spring Security) 이론

익명 블로그 V5(인증 블로그 V1) - 4 (이론)
이나겸's avatar
Nov 30, 2024
[스프링부트] 익명 블로그 V5 - 인증 블로그 V1 - 스프링 시큐리티(Spring Security) 이론
💡

Spring Security

Spring 프레임워크 기반의 애플리케이션의 인증(Authentication)과 인가(권한 부여, Authorization)등 보안 기능을 제공하는 강력한 프레임워크
웹 애플리케이션뿐만 아니라 REST API를 보호하는 데도 사용

주요 기능

인증(Authentication)

  • 사용자가 누구인지 확인하는 과정
  • 일반적으로 사용자 이름과 비밀번호, 또는 토큰 기반 인증(JWT, OAuth2 등)을 통해 수행되고 성공 시 사용자가 시스템에 접근 가능

인가(권한 부여)(Authorization)

  • 인증된 사용자가 애플리케이션 내에서 특정 리소스에 접근할 수 있는 권한이 있는지 확인
  • 사용자의 역할(Role)이나 권한(Authority)을 기반으로 접근을 제어

보안 필터(Security Filters)

  • 요청을 가로채고 인증 및 권한 부여 로직을 처리
  • 필터 체인(Filter Chain)을 통해 여러 필터를 조합하여 보안을 적용
    • UsernamePasswordAuthenticationFilter : 기본 로그인 폼 인증 처리
    • BasicAuthenticationFilter : HTTP Basic 인증 처리
    • SecurityContextPersistenceFilter : SecurityContext를 관리
    • ExceptionTranslationFilter : 인증/권한 예외 처리

보안 컨텍스트 (Security Context)

  • 인증 정보를 저장하는 컨테이너로, 현재 사용자의 인증 상태와 관련된 정보를 포함
  • 애플리케이션 내에서 보안 컨텍스트를 통해 사용자 정보를 조회

기본 보안 제공

  • Spring Boot와 함께 사용하면 기본적인 사용자 인증/인가 기능을 간단히 설정 가능
  • 디폴트로 기본 로그인 폼과 세션 기반 인증이 활성화

유연성

  • 커스터마이징을 통해 사용자 정의 인증 방식, 권한 체크, 필터 추가 가능
 

주요 구성 요소

AuthenticationManager

  • 인증을 처리하는 인터페이스로 다양한 인증 방법 지원
  • 인증이 성공하면 인증된 사용자 정보를 SecurityContext에 저장

UserDetailsService

  • 사용자 정보를 로드하는 인터페이스
  • 데이터베이스나 외부 시스템에서 사용자 정보를 조회하여 반환

GrantedAuthority

  • 사용자가 가지고 있는 권한을 나타내는 인터페이스
  • 사용자의 역할(Role)이나 특정 기능에 대한 권한 나타냄

Security Configuration

  • 보안 설정 정의하는 클래스
  • @EnableWebSecurity 어노테이션과 WebSecurityConfigurerAdapter 클래스 사용하여 보안 설정 커스터마이징 가능
 

Security Filter Chain 실행 위치

  • Apache Tomcat → SC(Spring Container) 진입 → Security Filter Chain 적용 → Dispatcher Servlet → Controller, Service, Repository → 데이터베이스
  • Dispatcher Servlet 전에 Security Filter Chain 적용됨 주의 ⇒ Security Filter도 Filter니까 요청 가로채서 실행되고 넘어감
    • notion image
 

Security 관련 이론 참고

[암호화의 salt]

💡

Salt

암호화에서 비밀번호를 안전하게 저장하기 위해 사용하는 임의의 값
  • 여러 사용자가 같은 비밀번호를 사용해도 각자의 비밀번호는 매번 다른 hash값(암호화)이 생성
  • 원본 비밀번호와 결합되어 hash화 ⇒ 미리 계산된 해시값을 이용한 공격(Rainbow Table) 방지
  • 임의적으로 생성되고 길이와 형식은 알고리즘마다 다를 수 있음

예시

$2a$10$0YhsiTbHSunUSqzM0wiFievEZn62g72WIToaN4Fo1YvM8vwYBM8eW
  • $2a$: bcrypt 암호화 알고리즘의 버전
  • $10$: Cost Factor (Work Factor)
    • 암호화 작업의 난이도(2의10제곱 = 1024번의 연산)
  • 마지막 달러 표시 다음의 첫 22자 : Salt
    • 임의로 생성된 값으로 비밀번호 해시화할 때 사용
  • 나머지 부분 : 해시화(암호화)된 비밀번호
    • salt와 원래 비밀번호가 결합된 후 이 값 생성

[bucrypt]

💡

bcrypt

비밀번호를 안전하게 저장하기 위해 설계된 암호화 해시 함수
  • 자동으로 고유한 Salt 생성
  • 암호화 연산의 난이도를 조정할 수 있는 Cost Factor(Work Factor) 제공 ⇒ 2의 거듭제곱으로 설정 ⇒ 숫자가 클수록 계산에 더 많은 시간이 소요돼서 공격자가 암호 해독하기 어려움
  • bcrypt의 해싱 결과는 항상 60자로 고정
  • bcrypt 결과 문자열에 Salt 포함되어 있어서 별도 관리할 필요 없음 ⇒ 데이터베이스 관리 및 보안 편리
  • 연산 시간이 입력 길이에 비례하지 않아서 타이밍 공격으로부터 안전
  • 비밀번호 길이가 달라도 해시화 시간은 일정

보안에 강한 이유

  • 비용 증가
    • 시간과 컴퓨팅 리소스가 증가함에 따라, cost factor를 높여도 기존의 해시값은 여전히 유효 ⇒ 시스템이 성능 향상에 따라 보안 강화할 수 있게 함
  • Rainbow Table 방지
    • salt를 사용하여 동일한 비밀번호라도 서로 다른 해시값을 생성하므로, 공격자가 사전 계산된 해시값을 사용한 Rainbow Table 공격을 수행 불가
  • Brute Force 방지
    • bcrypt는 반복 연산을 포함하고 있어, brute force 공격으로 비밀번호를 크랙하는 데 시간이 오래 걸림
  • 암호화 결과의 불가역성
    • bcrypt는 단방향 암호화(해시) 방식으로 설계되어, 암호화된 값을 원래 비밀번호로 복구 불가
 

[CSRF(Cross-Site Request Forgery)]

💡

CSRF

사이트 간 요청 위조
사용자가 자신도 모르는 사이에 다른 사이트에서 공격자가 의도한 악의적인 요청을 전송하도록 하는 웹 보안 취약점

CSRF 원리

  • 유효한 세션 쿠키
    • CSRF 공격은 사용자가 이미 타겟 웹사이트에 로그인된 상태에서, 해당 사이트와 유효한 세션 쿠키를 갖고 있을 때 발생
  • 피싱 또는 악성 사이트 방문
    • 공격자는 사용자를 피싱 이메일이나 악성 사이트로 유도하여, 해당 사이트에서 악의적인 스크립트를 실행
  • 악의적인 요청 전송
    • 사용자가 악성 사이트를 방문하면, 해당 사이트의 스크립트가 사용자의 브라우저를 통해 타겟 웹사이트로 요청을 전송
    • 브라우저는 타겟 웹사이트에 유효한 세션 쿠키를 자동으로 포함하여 요청을 보냄
  • 원치 않는 작업 수행
    • 타겟 웹사이트는 요청이 사용자로부터 온 것으로 간주하고, 요청된 작업을 수행 ⇒ 사용자의 계정 정보 변경이나 게시물 작성 등 가능

CSRF 방어 방법

  • CSRF 토큰 사용
    • 서버는 각 요청에 대해 고유한 CSRF 토큰을 생성하여 클라이언트에 전달하고, 클라이언트는 폼 데이터를 전송할 때 이 토큰을 함께 포함
    • 서버는 토큰의 유효성을 검증하여 CSRF 공격을 방지
  • 참조 헤더 검증
    • 서버는 요청의 참조 헤더(referrer)를 확인하여, 요청이 올바른 출처에서 발생했는지 검증
  • SameSite 쿠키 속성 사용
    • SameSite 쿠키 속성을 설정하여, 쿠키가 동일한 사이트에서 발생한 요청에서만 전송되도록 함
    • 다른 사이트에서 발생한 요청에서는 쿠키가 전송되지 않도록 함
 

[xss(Cross-Site Scripting)]

  • 웹 애플리케이션의 보안 취약점을 이용해 악성 스크립트를 사용자 브라우저에서 실행하도록 하는 공격
  • 공격자가 자바스크립트 코드를 삽입하여 서버 또는 브라우저에서 실행되도록 만듦
  • 사용자의 브라우저에서 악성 스크립트가 실행 ⇒ 사용자의 세션 쿠키 탈취, 개인정보 도용, 악성 코드 배포, 악성 사이트 리디렉션 등

XSS 방어 방법

  • 출력 데이터 인코딩
    • 사용자 입력 데이터를 HTML, JavaScript, URL 등 적절한 포맷으로 인코딩 ⇒ ex) HTML 컨텍스트에서는 <&lt;, >&gt; 등으로 변환
    • // Java의 예 (Spring Boot에서 사용) org.apache.commons.text.StringEscapeUtils.escapeHtml4(input);
  • 입력 데이터 검증
    • 서버와 클라이언트 모두에서 입력값 철저히 검증
    • 예상하지 않은 스크립트 태그나 특수 문자를 거부하거나 제거
    • if (!input.matches("^[a-zA-Z0-9 ]*$")) { throw new IllegalArgumentException("Invalid input!"); }
  • 콘텐츠 보안 정책(CSP, Content Security Policy)
    • 브라우저가 외부 스크립트를 실행하거나 인라인 스크립트를 허용하지 않도록 제어
    • Content-Security-Policy: default-src 'self'; script-src 'self';
  • HTTPOnly 쿠키 설정
    • 쿠키에 HTTPOnly 속성을 추가하여 자바스크립트에서 접근할 수 없도록 설정
    • Set-Cookie: session_id=abcd1234; HttpOnly; Secure;
  • DOM 조작 시 주의
    • 자바스크립트로 DOM을 조작할 때, 사용자 입력값을 직접적으로 삽입하지 않도록 주의 ⇒ ex) innerHTML 대신 textContent를 사용
    • // 안전한 방법 document.getElementById("output").textContent = userInput;
  • 보안 라이브러리 사용
    • 프레임워크에서 제공하는 보안 메서드 활용 ⇒ Spring Security, OWASP ESAPI 등

[HTTP Referrer]

  • 현재 페이지에 요청을 보낸 이전 웹 페이지의 URL을 나타내는 HTTP 헤더 필드
  • 사용자가 특정 페이지에 도달하기 전에 어떤 페이지에서 왔는지 정보를 제공 ⇒ 검색 엔진, 다른 웹사이트, 이메일 등의 링크 등
  • 웹 서버와 분석 도구가 트래픽의 출처를 파악할 수 있도록 도와줌 ⇒ 분석, 보안, 광고 등에 활용
Share article

Nakyeom's Study