주요 기능
인증(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니까 요청 가로채서 실행되고 넘어감

Security 관련 이론 참고
[암호화의 salt]
- 여러 사용자가 같은 비밀번호를 사용해도 각자의 비밀번호는 매번 다른 hash값(암호화)이 생성
- 원본 비밀번호와 결합되어 hash화 ⇒ 미리 계산된 해시값을 이용한 공격(Rainbow Table) 방지
- 임의적으로 생성되고 길이와 형식은 알고리즘마다 다를 수 있음
예시
$2a$10$0YhsiTbHSunUSqzM0wiFievEZn62g72WIToaN4Fo1YvM8vwYBM8eW$2a$: bcrypt 암호화 알고리즘의 버전
$10$: Cost Factor (Work Factor)- 암호화 작업의 난이도(2의10제곱 = 1024번의 연산)
- 마지막 달러 표시 다음의 첫 22자 : Salt
- 임의로 생성된 값으로 비밀번호 해시화할 때 사용
- 나머지 부분 : 해시화(암호화)된 비밀번호
- salt와 원래 비밀번호가 결합된 후 이 값 생성
[bucrypt]
- 자동으로 고유한 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 공격을 방지
- 참조 헤더 검증
- 서버는 요청의 참조 헤더(referrer)를 확인하여, 요청이 올바른 출처에서 발생했는지 검증
- SameSite 쿠키 속성 사용
- SameSite 쿠키 속성을 설정하여, 쿠키가 동일한 사이트에서 발생한 요청에서만 전송되도록 함
- 다른 사이트에서 발생한 요청에서는 쿠키가 전송되지 않도록 함
[xss(Cross-Site Scripting)]
- 웹 애플리케이션의 보안 취약점을 이용해 악성 스크립트를 사용자 브라우저에서 실행하도록 하는 공격
- 공격자가 자바스크립트 코드를 삽입하여 서버 또는 브라우저에서 실행되도록 만듦
- 사용자의 브라우저에서 악성 스크립트가 실행 ⇒ 사용자의 세션 쿠키 탈취, 개인정보 도용, 악성 코드 배포, 악성 사이트 리디렉션 등
XSS 방어 방법
- 출력 데이터 인코딩
- 사용자 입력 데이터를 HTML, JavaScript, URL 등 적절한 포맷으로 인코딩
⇒ ex) HTML 컨텍스트에서는
<→<,>→>등으로 변환
// 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