XSS(Cross Site Scripting)와 CSRF(Cross Site request forgery)+SSRF

mercure·2025년 5월 15일

공부

목록 보기
3/5
post-thumbnail

개요

XSS는 Cross Site Scripting 의 약자로, 한국어로 해석하면 사이트 간 스크립팅이다. 웹 상에서 가장 흔하게 발생할 수 있는 취약점으로 공격자가 악의적인 스크립트를 삽입하면 사용자가 원치 않는 스크립트를 실행하게 되며, 주로 쿠키,세션 탈취로 이어지는 공격이다.

CSRF는 Cross Site request forgery의 약자로, 한국어로 해석하면 사이트간 요청 위조이다. 사용자가 인증된 세션을 보유하고 있는 상태에서 공격자가 사용자 몰래 서버로 악의적인 요청을 전송하는 공격 기법을 말한다.

  • XSS는 공격자가 사용자의 브라우저에서 악성 스크립트를 실행시키는 것
  • CSRF는 공격자가 사용자의 인증된 세션을 이용하여 서버로 악의적 요청을 전송하는 것

그렇다면 이런 생각이 들 수 있다.

XSS를 통해 CSRF를 터트릴 수 있는가?

당연히 가능하다. 그러면 "XSS 범주안에 CSRF가 포함되어 있냐" 라고 묻는다면 그건 또 아니다. XSS 공격에서 CSRF로 이어지는 체인이 가능하다는 것이다.

그리고 둘의 차이점은 공격 대상에 있는데 XSS의 경우 사용자가 공격대상이고 사용자의 브라우저에서 javascirpt가 실행되는 것이 핵심이다. CSRF는 서버가 공격대상이며 서버를 속이는 위조된 요청을 보내는 것이다.

XSS(Cross Site Scripting)

Stored XSS

공격자가 스크립트를 웹 애플리케이션의 서버에 영구적으로 저장하여, 해당 콘텐츠를 열람하는 사용자가 악성 스크립트를 실행하도록 하는 공격

Example

댓글 , 게시글에 악성스크립트 삽입 -> 사용자 열람시 트리거

Refelected XSS

공격자가 악성 링크를 통해 피해자를 특정 URL로 유도하여, 사용자의 브라우저에서 즉시 악성 스크립트를 실행하도록 하는 공격

example

이메일, 메시지 악성 스크립트가 포함된 링크 삽입 -> 사용자가 링크를 타고 들어올 시 스크립트 트리거

DOM Based XSS

클라이언트 측에서 발생하는 취약점으로, 서버 응답에는 악성 스크립트가 포함되지 않지만, 클라이언트 측 JavaScript 코드가 사용자 입력을 통해 DOM(Document Object Model)을 동적으로 조작하면서, 악성 스크립트가 실행될 수 있는 공격

example

URL 파라미터로 전달된 값이 클라이언트 JavaScript에 의해 DOM에 반영되고 실행

위와 같이 정리할 수 있겠다. 그러면 또 아래와 같은 궁금증이 생긴다.

XSS는 Stored, Reflected, DOM으로 나뉘나요?

아니다. XSS는 기본적으로 Stored XSS(저장형 XSS)Reflected XSS(반사형 XSS)로 구분된다. DOM 기반 XSS(DOM-Based XSS)는 클라이언트 측에서 발생하는 특수한 XSS로, 서버 응답 자체에는 악성 스크립트가 포함되지 않지만, 클라이언트의 JavaScript 코드가 DOM을 동적으로 조작하면서 악성 코드가 실행되는 취약점이다.

즉, Stored XSS와 Reflected XSS는 서버에서 전달된 스크립트가 실행되지만, 클라이언트에서 직접 DOM을 수정하면서 발생하는 점이 다르다.

그럼 이제 XSS를 정리해보았으니 공격자 입장에서 어떤 방어기법이 있는지 알아보자

XSS 방어 방법

1. 출력 시 컨텍스트에 맞는 인코딩 적용
	- HTML에서는 <, >, &를 HTML 엔티티로 변환하고, JavaScript에서는 문자열 내 특수 문자를 이스케이프 처리한다.
2. 입력값 검증 및 화이트리스트 기반 필터링
3. HTML Sanitization 수행
	- 사용자로부터 HTML 입력을 허용할 경우, 허용된 태그와 속성만 남기고 나머지를 제거하는 sanitization 사용
4. Content Security Policy(CSP) 설정
	- CSP는 응답 헤더에 포함되어 있으며, 사이트 내(self)와 신뢰된 CDN을 정의하여 지정된 출처의 리소스만 로드할 수 있도록 제한한다.
5. DOM 기반 XSS 방지
	- 클라이언트 측 JavaScript에서 사용자 입력을 DOM에 직접 삽입할 때, innerHTML 대신 textContent나 setAttribute 사용을 권장한다. 또는 sanitization 사용
6. 보안 속성 설정
	- 쿠키에 HttpOnly, Secure, SameSite 속성을 적용하여 클라이언트 측에서 접근하지 못하도록 설정할 수 있다.
	- **SameSite**는 쿠키의 전송을 제어하는 쿠키 속성으로, 동일 사이트에서 발생한 요청에서만 쿠키를 전송하거나 크로스 사이트 요청에서의 쿠키 전송을 제한할 수 있다.
7. 보안 프레임워크 및 라이브러리 활용
	- React, Angular, Vue.js 등 최신 프론트엔드 프레임워크는 기본적으로 XSS 방지 메커니즘을 제공한다.
8. WAF(Web Application Firewall)
	- 웹 애플리케이션으로 들어오는 트래픽을 분석해 XSS, SQLi 같은 악성 요청을 차단할 수 있다.

CSRF(Cross Site request forgery)

CSRF는 사용자가 인증된 세션을 보유하고 있는 상태에서 공격자는 사용자의 의도와 무관하게 서버로 악의적인 요청을 유도하는 공격이다.

정리하면 사용자가 로그인된 상태에서 외부 사이트를 방문하면, 공격자가 해당 사이트를 통해 서버로 요청을 자동으로 전송할 수 있으며, 이는 사용자의 권한으로 처리된다.

example

간단한 예시를 들어보면 모바일 메신저 서비스의 CSRF 취약점을 악용한 예시이다. 공격자가 아래의 메시지를 누군가에서 메신저에서 보낸다.

이벤트에 당첨되셨습니다. 얼른 주소를 보내주세요.
https://messenger.com/send_message?message=안녕하세요%20이벤트%20참여해보세요!&to=all

피해자가 로그인된 상태에서 링크를 클릭하면, 모든 친구에게 자동으로 메시지가 발송된다. 피해자는 공격자가 작성한 메시지를 친구들에게 전송하게 되어 스팸 메시지를 유포하게 된다.

XSS-CSRF 시나리오

그럼 XSS를 통한 CSRF 체인은 그래서 어떻게 해요?

1. Stored XSS 활용

이번에는 그래도 POST 요청으로 들고 와봤다. 가상의 은행에서 post요청으로 송금 처리를 하며, 게시글에 공격자가 아래와 같은 XSS 페이로드가 적힌 게시글 작성을 한다.

<script>
  document.addEventListener("DOMContentLoaded", function() {
    setTimeout(() => {
      fetch("https://bank.com/transfer", {
        method: "POST",
        credentials: "include", // 세션 쿠키 자동 포함
        headers: {
          "Content-Type": "application/x-www-form-urlencoded"
        },
        body: "to=attacker&amount=1000"
      }).then(response => {
        if (response.ok) {
          console.log("Success");
        } else {
          console.error("Fail");
        }
      });
    }, 500); 
  });
</script>

2. 피해자가 게시글 열람 (XSS 트리거)

피해자가 bank.com에 로그인된 상태로 공격자가 작성한 게시글을 열람한다.
Stored XSS가 실행되며 CSRF 코드가 실행된다.

3. CSRF

앞선 스크립트문이 실행되며 POST요청으로 공격자에게 1000원을 송금하게 된다.
서버는 피해자의 세션 쿠키를 확인하여, 피해자가 인증된 사용자로 인식하고 요청을 처리한다. 결과적으로 1000원을 송금하게 된다

CSRF token

대표적 방법인 CSRF 토큰에 대해서만 자세히 알아보도록 하자.

CSRF 토큰은 사용자의 요청이 실제 사용자로부터 온 것임을 증명하기 위해 발급하는 임의의 문자열이다.

이 토큰은 보통 사용자가 로그인하면 서버에서 세션과 함께 생성되며,
HTML 폼의 hidden 필드나 HTTP 요청 헤더에 포함되어 전송된다.서버는 요청이 올 때마다 세션에 저장된 토큰 값과 요청에 포함된 토큰이 일치하는지 확인하여 정상 요청인지 여부를 판단한다.

근데 웹사이트에 쿠키로 csrf_token이 저장되어 있는 경우가 있다.

XSS로 쿠키 탈취가능한데 , XSS로 CSRF token까지 털 수 있나요?

맞다. XSS가 있다면 CSRF 토큰이 의미가 없다. XSS를 우선적으로 막도록 하자.

CSRF 방어방법 정리

1. CSRF 토큰 사용 (Synchronizer Token Pattern)
2. SameSite 쿠키 설정
3. Referer 및 Origin 헤더 검증
	- 서버는 요청의 Referer 또는 Origin 헤더를 확인하여 요청이 신뢰할 수 있는 출처에서 발생했는지 검증	합니다.
4. 사용자 인증 시 재확인
5. 안전한 HTTP 메서드 사용(GET 메서드 피하기)
6. 사용자 입력 검증 및 화이트리스트 기반 필터링
7. 프레임워크 및 보안 라이브러리 활용
8. CSP
	-js의 외부 실행을 제한 , xss 발생해도 외부 코드 실행을 막을 수 있음

SSRF와 차이 (Server Side Request Forgery)

추가적으로 SSRF와 CSRF의 경우 다른데 이 경우 요청 주체가 다르다. 우선 CSRF의 경우 공격자가 피해자의 권한으로 위조하여 요청을 보내도록 만드는 것이고 , SSRF의 경우 서버 자체가 다른 서버나 자신의 서버로 위조된 요청을 보내도록 만든 것이다.

profile
하루에 한걸음씩

0개의 댓글