1. CSRF와 XSS
1-1 CSRF(Cross Site Request Forgery)란?
- CSRF는 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행동을 웹 애플리케이션에서 실행하게 만드는 공격 방법이다.
- 즉, 인증된 사용자의 권한을 이용해 의도하지 않은 요청을 보내는 것을 의미한다.
CSRF 공격 방식
대표적인 공격방식은 위 사진과 같다.
- 악성 스크립트등을 통해 조작할 내용의 게시글 작성
- 악성 게시글은 DB에 저장됨
- 관리자 또는 특정 사용자(희생자)가 공격자가 작성한 게시글을 클릭
- 악성 게시글은 사용자가 웹 클라이언트를 통해 읽혀지는 동안 클라이언트 언어로 인식되어 동작
- 악성 스크립트가 동작하며 특정 사용자의 권한이 필요할 경우 해당 권한을 통해 동작함
- 희생자에겐 정상적인 게시글로 동작
예를 들어, 사용자가 로그인 상태에서 공격자가 준비한 해로운 웹사이트를 방문할 경우, 이 사이트에서 사용자 몰래 공격 대상 웹 애플리케이션에 요청을 보내게 된다.
이 때, 사용자는 자신도 모르는 사이에 공격자가 의도한 행동(비밀번호 변경, 금융 거래 등)을 하게 된다.
CSRF의 특징
- 사용자 모르게 실행:
- 사용자는 자신의 의지와는 무관하게, 공격자가 의도한 행동을 웹 애플리케이션에서 수행하게 된다.
- 사용자 인증 정보 활용:
- CSRF 공격은 사용자가 이미 인증된 상태, 즉 로그인된 상태를 이용한다.
- 공격자는 피해자의 인증 정보를 직접 획득하지 않고도 공격을 수행할 수 있다.
- 간단한 공격 방법:
- 공격자는 피해자가 공격에 사용될 링크나 이미지 등을 클릭하게 만드는 것만으로도 공격을 수행할 수 있다.
- 횡단 사이트 요청:
- CSRF는 다른 원본(origin) 또는 사이트에서 발생한 요청을 통해 공격을 수행한다.
- 방어 기법의 중요성:
- CSRF 공격은 많은 웹 애플리케이션에서 발생할 수 있으며, 효과적인 방어 기법을 적용하지 않으면 큰 피해를 입을 수 있다.
- 따라서, CSRF 토큰, SameSite 쿠키 속성 설정, Referer 검증 등의 방어 기법이 중요하다.
CSRF 방어 기법
- 토큰 사용:
- 서버에서 생성한 토큰을 클라이언트에게 전달하고, 클라이언트는 요청 시 이 토큰을 포함시켜 전송한다.
- 서버는 요청을 받을 때마다 토큰을 검증하여 CSRF 공격을 방어한다.
- SameSite 쿠키 속성 사용:
- 쿠키에 SameSite 속성을 설정하여, 쿠키가 다른 사이트의 요청과 함께 전송되지 않도록 한다.
- 이를 통해 사용자가 신뢰하는 사이트에서만 쿠키가 전송되도록 제한한다.
- Referer 검증:
- HTTP Referer 헤더를 검증하여 요청이 신뢰할 수 있는 도메인으로부터 발생했는지 확인한다.
- 사용자 인증 요구:
- 중요한 작업을 수행하기 전에 사용자에게 다시 인증(예: 비밀번호 입력, 이메일 확인 등)을 요구한다.
- 캡챠 사용:
- 회원정보 변경, 게시글 작성 등 CSRF의 공격을 막아야 하는 페이지에서 캡챠를 사용해 인증이 가능한 것만 요청을 처리해주는 방법이 있다.
- 캡챠는 랜덤 이미지를 통해 인증이 되므로 사용자 몰래 요청하는것이 불가능 하다는 장점이 있다.
1-2 XSS(Cross Site Scripting)란?
- XSS는 웹 애플리케이션에서 발생하는 취약점 중 하나로, 공격자가 웹 페이지에 악성 스크립트를 삽입하여, 웹 페이지를 방문하는 사용자의 브라우저에서 그 스크립트가 실행되게 만드는 공격 방법이다.
- 이 공격을 통해 사용자의 세션 쿠키, 토큰 등을 탈취하거나, 사용자를 가장하여 웹 애플리케이션에 대한 악의적인 행동을 할 수 있다.
XSS 공격 유형
- 저장된 XSS (Stored XSS)
- 공격자가 웹 애플리케이션의 데이터베이스에 악성 스크립트를 저장하고, 이를 조회하는 사용자의 브라우저에서 실행되게 만드는 방식이다.
- 예를 들어, 게시판에 악성 스크립트가 포함된 글을 작성하여, 이 글을 읽는 사용자의 브라우저에서 스크립트가 실행될 수 있다.
- 반사된 XSS (Reflected XSS)
- 사용자가 제공한 데이터를 서버에서 즉시 처리하여, 그 결과를 사용자에게 다시 보여줄 때 이 데이터에 포함된 악성 스크립트가 실행되는 방식이다.
- 예를 들어, 검색 결과 페이지에서 검색어에 악성 스크립트를 삽입하여, 검색 결과를 조회하는 사용자의 브라우저에서 이 스크립트가 실행될 수 있다.
- DOM 기반 XSS (DOM-based XSS)
- 웹 페이지의 DOM(Document Object Model)을 조작하여 악성 스크립트가 실행되게 만드는 방식이다.
- 이 유형의 XSS는 웹 페이지의 클라이언트 측 코드를 통해 발생하며, 서버 측 처리 없이도 발생할 수 있다.
XSS 방어 기법
- 입력값 검증 및 이스케이핑
- 사용자 입력값에 대한 검증을 엄격하게 수행하고, HTML, JavaScript 등에서 사용될 수 있는 특수 문자를 이스케이핑 처리하여, 악성 스크립트의 실행을 방지한다.
- 콘텐츠 보안 정책(CSP) 적용
- 콘텐츠 보안 정책(CSP)을 설정하여, 웹 페이지에서 실행될 수 있는 스크립트의 출처를 제한한다.
- 이를 통해 외부 악성 스크립트의 실행을 방지할 수 있다.
- HTTPOnly 쿠키 사용
- 쿠키에 HTTPOnly 속성을 설정하여, JavaScript를 통한 쿠키 접근을 차단한다.
- 이를 통해 XSS 공격을 통한 사용자 세션 탈취를 방지할 수 있다.
1-3 CSRF와 XSS 비교
- XSS가
사용자가 특정 사이트를 신뢰
하기 때문에 발생하는 문제라면, CSRF는 특정 사이트가 사용자를 신뢰
하기 때문에 발생하는 문제이다.
- XSS는
클라이언트의 브라우저
에서 발생하는 문제이고, CSRF는 서버
에서 발생하는 문제이다.
- XSS는 사용자의
쿠키
를 탈취할 수 있고, CSRF는 서버로부터 권한
을 탈취할 수 있다.
| CSRF | XSS |
---|
방법 | 악성 스크립트가 클라이언트에서 실행 | 권한을 도용당한 클라이언트가 가짜 요청을 서버에 전송 |
원인 | 사용자가 특정 사이트를 신뢰 | 특정 사이트가 사용자를 신뢰 |
공격대상 | 클라이언트 | 서버 |
목적 | 쿠키, 세션 갈취, 웹사이트 변조 | 권한 도용 |
2. Spring Security에서의 CSRF 보호
- Spring Security는 기본적으로 CSRF 보호 기능을 제공하며, CSRF 토큰은 자동으로 생성된다.
- 모든 PATCH, POST, PUT, DELETE 메소드에 대한 요청에 대해 CSRF 토큰 검증을 수행한다.
Spring Security에서 CSRF 보호는 기본 설정이므로, 명시적으로 활성화하는 코드는 필요하지 않다.
아래는 security-context.xml
의 예시이다.
<security:http xmlns:security="http://www.springframework.org/schema/security" use-expressions="true">
<security:intercept-url pattern="/" access="permitAll"/>
<security:intercept-url pattern="/home" access="permitAll"/>
<security:intercept-url pattern="/**" access="isAuthenticated()"/>
<security:form-login login-page="/login" permit-all="true"/>
<security:logout permit-all="true"/>
</security:http>
기본적으로 Spring Security는 CSRF 보호를 활성화하지만, 경우에 따라서는 비활성화할 수도 있다.
하지만 보안을 위해서는 가능한 CSRF 보호 기능을 활성화하는 것이 좋다.
참고: https://kk-7790.tistory.com/73
참고: https://velog.io/@9rganizedchaos/%ED%86%A0%ED%81%B0-%ED%86%A0%ED%81%B0-%ED%86%A0%ED%81%B0
참고: https://securitysouls.com/a-tale-of-cross-site-request-forgery-csrf/
참고: https://velog.io/@haizel/XSS%EC%99%80CSRF-%EC%B0%A8%EC%9D%B4%EC%A0%90-%EB%B0%8F-%EB%8C%80%EC%9D%91-%EB%B0%A9%EC%95%88
참고: https://no-more-assignment.tistory.com/81