dev-sohee 님의 블로그
웹 보안의 취약점 1탄 : XSS, CSRF 공격 기법 본문
웹의 가장 큰 장점 중 하나는 인터넷 연결만 있으면 언제 어디서나 접근할 수 있다는 것입니다. 하지만 이 말은 곧 그만큼 보안이 취약하다는 뜻이기도 합니다. 당장 브라우저의 개발자 도구만 열어도 DOM이 어떻게 작성되어 있는지, 어떤 서버와 통신하는지 등의 각종 정보들을 열람할 수 있고 쿠키 값도 변경하여 클라이언트의 요청을 위변조할 수 있습니다. 오늘은 웹 보안 취약점을 이용한 XSS, CSRF 공격 기법과 웹 보안 기법 중 하나인 CORS에 대해 알아보겠습니다.
* XSS(Cross Site Scripting)
* CSRF(Cross Site Request Forgery)
# XSS
XSS란 Cross Site Scripting의 약자로 CSS라고 하는 것이 맞지만 CSS가 이미 Cascading Style Sheets의 약어로 사용되고 있어서 XSS라고 합니다. XSS는 악성 스크립트를 웹 페이지에 삽입하여 사용자의 브라우저에서 개발자가 의도하지 않은 기능이 실행되도록 하는 공격 기법입니다.
XSS 종류
1. Reflected XSS
- 공격 방식: 공격자가 미리 XSS 공격에 취약한 웹사이트를 탐색하고, 악성 스크립트를 포함한 URL을 사용자에게 노출시킵니다. 사용자가 해당 URL을 클릭할 경우, 취약한 웹 사이트의 서버에 악성 스크립트가 포함된 URL을 통해 request를 전송하고, 웹 서버에서는 해당 스크립트를 포함한 response를 전송하게 됩니다.
- 예시: 공격자는 다음과 같은 악성 URL을 생성하여 사용자의 메일로 전송하거나 댓글에 공개하여 사용자에게 노출합니다.
http://www.example-shop.com/search?q=<script>alert('Your session has expired. Please login again.');</script>
이 URL은 검색 파라미터 q에 경고창을 띄우는 악성 스크립트를 포함하고 있습니다. 공격자는 이 URL을 피해자에게 이메일, 소셜 미디어 메시지, 또는 채팅 링크 등으로 보내 피해자가 클릭하도록 유도합니다. 피해자가 이 링크를 클릭하면, 웹 브라우저는 해당 URL을 열고 서버로부터 검색 결과 페이지를 요청합니다. 서버는 q 파라미터에 포함된 값을 그대로 검색 결과 페이지에 반영하여 응답을 생성합니다. 응답 페이지에서 악성 스크립트가 포함된 부분이 피해자의 브라우저에서 그대로 실행되어 다음과 같은 경고창이 표시됩니다.
Your session has expired. Please login again.
2. Stored XSS
- 공격 방식: 공격자가 악성 스크립트를 웹 애플리케이션의 데이터베이스나 저장소에 영구적으로 삽입하여, 해당 데이터를 읽는 모든 사용자의 브라우저에서 스크립트가 실행되도록 하는 공격입니다.
- 예시: 공격자가 한 사이트에 악성 스크립트가 포함된 게시글을 작성합니다. 이 게시글은 데이터베이스에 저장되고 사이트의 모든 사용자는 이 글을 볼 수 있습니다. 다른 사용자가 해당 게시글을 읽기 위해 페이지를 열 때, 저장된 악성 스크립트가 자동으로 실행됩니다. 만일 사용자의 쿠키 정보를 읽고 전송하는 공격을 했다면, 사용자의 브라우저는 쿠키 정보를 공격자의 서버로 전송합니다. 공격자는 여러 사용자의 세션 쿠키를 탈취하여, 해당 사용자의 권한으로 웹사이트에 접근할 수 있게 됩니다. 예를 들어, 공격자는 관리자의 쿠키를 탈취하여 관리자로 로그인한 것처럼 행동할 수 있으며, 이는 전체 웹사이트에 대한 완전한 제어를 의미할 수 있습니다.
<script>alert('XSS Attack!');</script>
공격자가 댓글란에 위와 같은 악성 스크립트를 입력하면 사용자가 이 스크립트가 그대로 서버에 저장되고, 사용자가 해당 댓글을 클릭했을 때 다음과 같은 경고창이 표시됩니다.
XSS Attack!
위의 예시는 경고창이 뜨는 간단한 악성 스크립트지만 실제로는 사용자의 개인정보가 공격자의 이메일로 발송되는 등의 위험 상황이 발생할 수 있습니다.
3. DOM-based XSS
- 공격 방식: DOM 구조를 이용하여 요소들을 수정하거나 추가하는 등 동적 행위를 할 때 접근하는 JavaScript에 악성 스크립트를 삽입하여 클라이언트 측 브라우저에서 악성 스크립트가 실행되도록 하는 공격입니다. Reflected XSS와 같이 동적 페이지를 구성하는 과정 상에서 발생되는 XSS 공격이지만, Reflected XSS는 서버 측에서 동적 페이지를 구성하는 환경에서 발생되는 XSS입니다. 반면에 DOM Based XSS는 클라이언트 측에서 사용자 입력 값을 통해 동적 페이지를 구성하는 환경에서 발생되는 XSS입니다. 즉, 요청이 서버로 전송되지 않고 클라이언트 브라우저에서 공격이 이루어지는 특징을 가지고 있습니다.
- 예시: 사용자가 악성 스크립트가 담긴 URL을 클릭하면, 브라우저는 악성 스크립트를 읽어들입니다. 이후 DOM을 조작하는 악성 스크립트가 실행되면서 개발자의 의도와 무관한 동작이 발생할 수 있습니다.
XSS 방어 기법
1. 입력 값 검증
: 데이터가 입력되기 전이나, 입력된 데이터를 서버에 전달하기 전에 프론트에서 검증하는 것이 좋습니다. 입력 형식(이메일, URL, 숫자 등)과 데이터 길이 등을 명확히 정의하고, 이 형식에 맞지 않는 데이터는 거부하거나 무효화합니다.
2. 출력 인코딩
: 입력된 데이터가 HTML, JavaScript, CSS, 또는 URL에 포함되어 브라우저에서 해석될 때, 해당 데이터가 코드로 실행되지 않도록 인코딩합니다.
예시)
변경 전 | 변경 후 | 변경 전 | 변경 후 |
& | & | " | " |
< | < | ' | ' |
> | > | / | / |
( | ( | ) | ) |
3. 콘텐츠 보안 정책(Content Security Policy, CSP)
: CSP는 웹사이트가 로드할 수 있는 리소스의 출처를 제어하여 XSS 공격을 방어하는 보안 기법입니다. CSP를 통해 스크립트 소스, 스타일 시트, 이미지, 폰트 등 다양한 리소스의 출처를 제한할 수 있습니다.
예시) 웹 서버에서 CSP 헤더를 설정합니다. 아래 정책은 동일 출처와 신뢰할 수 있는 CDN에서만 스크립트를 로드할 수 있게 제한합니다.
Content-Security-Policy: script-src 'self' https://trusted.cdn.com;
**CDN(Content Delivery Network)이란? : CDN은 전 세계에 분산된 서버 네트워크로, 웹사이트의 성능을 최적화하는 중요한 기술입니다. 웹사이트에 대한 트래픽을 여러 서버에 분산시켜, 한 서버에 너무 많은 부하가 걸리는 것을 방지합니다. 이를 통해 웹사이트의 속도와 안정성이 크게 향상됩니다.
# CSRF
CSRF는 Cross Site Request Forgery의 약자로, 사이트간의 요청 위조를 뜻합니다. 이는 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위를 특정 웹사이트에 요청하게 하는 공격입니다. 예를 들어, 사용자의 암호를 변경하거나 자금 이체 등의 동작을 수행하게 할 수도 있습니다.
CSRF 동작 원리
CSRF가 성공하려면, 아래 3가지 조건이 만족되어야 합니다.
- 사용자는 보안이 취약한 서버로부터 이미 로그인되어 있는 상태여야 합니다.
- 쿠키 기반의 서버 세션 정보를 획득할 수 있어야 합니다.
- 공격자는 서버를 공격하기 위한 요청 방법에 대해 미리 파악하고 있어야 합니다. (예상하지 못한 요청 매개변수가 없어야 합니다)
이 조건이 만족되면 다음과 같은 과정을 통해 CSRF 공격을 할 수 있습니다.
- 사용자는 보안이 취약한 서버에 로그인합니다.
- 서버에 저장된 세션 정보를 사용할 수 있는 세션 ID가 사용자의 브라우저 쿠키에 저장됩니다.
- 공격자는 사용자가 악성 스크립트 페이지를 누르도록 유도합니다.
- 사용자가 악성 스크립트가 작성된 페이지에 접근시 웹 브라우저에 의해 쿠키에 저장된 세션 ID와 함께 서버로 요청됩니다.
- 서버는 쿠키에 담긴 세션 ID를 통해 해당 요청이 인증된 사용자로부터 온 것으로 판단하고 처리합니다.
CSRF 방어 기법
- CSRF 토큰 사용
: 각 요청에 대해 고유한 CSRF 토큰을 생성하고, 서버는 이 토큰을 검증하여 요청이 유효한지 확인합니다. 이 토큰은 사용자의 세션과 연결되어 있으며, 공격자는 이를 예측하거나 재사용할 수 없습니다. - Referer 헤더 검증
: 요청이 올바른 출처에서 발생했는지 확인하기 위해, 서버는 요청의 Referer 헤더를 검증할 수 있습니다. 그러나 이 방법은 헤더를 변경할 수 있는 경우가 있기 때문에 보조적인 방어 기법으로 사용됩니다.
XSS, CSRF를 통해 웹 어플리케이션이 직면할 수 있는 웹 보안의 취약점과 중요성을 다시 한번 깨닫게 되었습니다. 특히, XSS 공격은 사용자 데이터의 탈취뿐만 아니라 악성 코드 유포로 이어질 수 있다는 점에서 경각심을 느꼈습니다. 웹 개발 과정에서 보안은 절대적으로 우선시되어야 하며, 단순한 기능 구현을 넘어서서 사용자와 시스템의 안전을 보장할 수 있는 코드를 작성하는 것이 얼마나 중요한지 깊이 느끼게 되었습니다.
'웹' 카테고리의 다른 글
트랜잭션 격리 수준이란? 데이터베이스 일관성의 비법 (0) | 2024.08.24 |
---|---|
서버 간 세션 불일치 문제, 이렇게 해결한다(Sticky Session, Session Clustering, In-Memory DB) (0) | 2024.08.24 |
War(Web Application Archive) 파일 구조 파헤치기 (0) | 2024.08.17 |
EDA(Event-Driven Architecture) 쉽게 이해하기 (0) | 2024.08.17 |
HTTP 상태 코드: 웹 요청의 결과 해석하기 (0) | 2024.08.11 |