보안

XSS(Cross-Site Scripting)와 CSRF(Cross-Site Request Forgery)의 차이점과 방어 방법

♠디지털 모험일지♠ 2024. 12. 8. 19:41
728x90
반응형
SMALL

XSS (Cross-Site Scripting)와 CSRF (Cross-Site Request Forgery)

XSS와 CSRF는 모두 웹 애플리케이션에서 발생하는 보안 취약점이지만, 공격 방식과 목표가 다릅니다.


1. XSS (Cross-Site Scripting)

정의

XSS는 공격자가 웹 페이지에 악성 스크립트(JavaScript 등)를 삽입하여 다른 사용자의 브라우저에서 실행되도록 하는 공격입니다. 이를 통해 사용자의 세션, 쿠키, 또는 민감한 정보를 탈취하거나, 악성 코드 실행이 가능합니다.

목표

  • 사용자 데이터를 탈취: 세션 쿠키, 로그인 정보 등.
  • 악성 코드 실행: 피해자의 브라우저에서 악성 동작 수행.
  • 웹 페이지 변조: 사용자에게 잘못된 정보 제공.

유형

  1. Stored XSS: 악성 스크립트가 서버에 저장되어 여러 사용자에게 전달.
  2. Reflected XSS: 입력값이 즉시 반영되어 악성 스크립트 실행.
  3. DOM-based XSS: 클라이언트 측에서 DOM 조작을 통해 발생.

방어 방법

  1. 입력값 검증 및 인코딩
    • 사용자 입력값을 철저히 검증하고 HTML, JavaScript로 실행되지 않도록 인코딩.
    • : <script> 같은 태그를 허용하지 않음.
  2. Content Security Policy (CSP)
    • 브라우저가 허용된 소스에서만 스크립트를 실행하도록 설정.
  3. HTTPOnly 쿠키 사용
    • 쿠키에 HTTPOnly 속성을 추가하여 JavaScript에서 쿠키 접근 차단.

2. CSRF (Cross-Site Request Forgery)

정의

CSRF는 사용자가 의도하지 않은 요청을 실행하도록 속이는 공격입니다. 공격자는 사용자의 인증 정보를 악용하여 사용자가 승인하지 않은 작업(예: 계좌 이체, 비밀번호 변경 등)을 실행합니다.

목표

  • 비인가 작업 실행: 사용자가 모르게 중요한 요청(데이터 수정, 송금)을 전송.
  • 사용자의 신뢰 악용: 서버는 요청이 사용자의 요청이라고 오인.

동작 방식

  1. 사용자가 은행 사이트에 로그인하여 세션 유지.
  2. 공격자가 악성 사이트를 방문하도록 유도.
  3. 악성 사이트가 사용자의 인증된 세션으로 은행 서버에 요청을 전송.

방어 방법

  1. CSRF 토큰 사용
    • 서버가 CSRF 토큰을 생성해 클라이언트에 전달. 서버는 요청 시 이 토큰을 확인.
  2. Referer 헤더 검사
    • 요청의 출처(URL)를 확인하여 비정상적인 출처에서 온 요청 차단.
  3. 사용자 인증 강화
    • 중요한 작업에 대해 추가 인증 요구(예: 비밀번호 재입력, OTP).

3. XSS와 CSRF의 차이점

특성 XSS CSRF
공격 대상 클라이언트(사용자 브라우저) 서버
공격 방식 악성 스크립트 삽입 및 실행 인증된 사용자의 권한을 악용하여 요청 전송
주요 목표 사용자 데이터 탈취, 브라우저에서 악성 동작 수행 비인가된 요청을 실행
발생 원인 사용자 입력값에 대한 검증 부족 서버가 요청의 출처를 확인하지 않음
방어 방법 입력값 검증, CSP, HTTPOnly 쿠키 CSRF 토큰, Referer 검증, 추가 인증

4. HTML 예제

XSS 예제

<!-- 취약한 코드 -->
<form action="/search" method="GET">
  <input type="text" name="query">
  <button type="submit">Search</button>
</form>

<!-- 사용자가 입력값에 <script> 삽입 -->
<!-- 예: /search?query=<script>alert('XSS!')</script> -->

방어 코드 (XSS 방지):

<form action="/search" method="GET">
  <input type="text" name="query" oninput="sanitizeInput(this)">
  <button type="submit">Search</button>
</form>

<script>
  // 사용자 입력값 검증
  function sanitizeInput(input) {
    input.value = input.value.replace(/</g, "&lt;").replace(/>/g, "&gt;");
  }
</script>

CSRF 예제

취약한 코드:

<!-- 사용자가 로그인 상태에서 이 코드를 포함한 악성 페이지를 방문 -->
<form action="https://bank.com/transfer" method="POST">
  <input type="hidden" name="account" value="attacker_account">
  <input type="hidden" name="amount" value="1000">
  <button type="submit">Click Me!</button>
</form>

방어 코드 (CSRF 토큰 사용):

<!-- 서버에서 CSRF 토큰 생성 -->
<form action="https://bank.com/transfer" method="POST">
  <input type="hidden" name="csrf_token" value="123456abcdef">
  <label for="account">Account:</label>
  <input type="text" name="account" id="account">
  <label for="amount">Amount:</label>
  <input type="text" name="amount" id="amount">
  <button type="submit">Transfer</button>
</form>

백엔드에서 토큰 검증 (예: Python Flask):

@app.route('/transfer', methods=['POST'])
def transfer():
    token = request.form.get('csrf_token')
    if not token or token != session['csrf_token']:
        abort(403)  # Forbidden
    # Transfer logic here

5. 용어 설명

용어 설명
스크립트 (Script) 웹 브라우저에서 실행되는 코드. 주로 JavaScript로 작성되며, 동적인 동작을 구현.
쿠키 (Cookie) 웹사이트가 사용자 브라우저에 저장하는 작은 데이터. 세션 유지나 사용자 추적에 사용.
HTTPOnly 쿠키 브라우저의 JavaScript에서 접근할 수 없는 쿠키로, 보안을 강화.
세션 (Session) 사용자가 서버와 연결된 상태를 유지하기 위한 정보. 보통 쿠키를 통해 관리.
CSRF 토큰 CSRF 공격 방지를 위해 서버에서 생성한 임시 값. 클라이언트가 요청할 때마다 서버에서 이 값을 확인하여 요청의 정당성을 보장.
CSP (Content Security Policy) 브라우저가 신뢰할 수 있는 콘텐츠만 로드하도록 제한하는 보안 정책.
Referer 헤더 요청이 어디서부터 왔는지를 나타내는 HTTP 헤더. CSRF 방지에 사용.

6. 요약

  • XSS는 사용자 브라우저에서 악성 스크립트를 실행해 데이터를 탈취하는 공격으로, 입력값 검증과 CSP 적용으로 방어.
  • CSRF는 사용자가 의도하지 않은 요청을 실행하도록 속이는 공격으로, CSRF 토큰과 Referer 검증으로 방어.
반응형
SMALL