웹 보안은 현대 웹 개발에서 가장 중요한 측면 중 하나입니다. 사용자의 개인 정보와 데이터를 보호하고 웹 애플리케이션의 안전성을 유지하는 것은 모든 웹 개발자들에게 필수적인 과제입니다. 그 중에서도 CSRF(Cross-Site Request Forgery)
와 XSS(Cross-Site Scripting)
는 가장 흔하고 치명적인 웹 보안 공격 중 하나로 알려져 있습니다.
이번 글에서는 CSRF와 XSS에 대해 알아보고, 이러한 공격으로부터 웹 애플리케이션을 보호하는 방법에 대해 다루어보겠습니다. 보안의 중요성을 인지하고, 안전한 웹 애플리케이션을 개발하기 위한 필수적인 지식을 습득하기 위해 기록합니다.
CSRF는 공격자가 사용자의 인증된 세션을 이용하여 사용자가 의도하지 않은 요청을 서버에 전송하도록 유도하는 공격입니다. 이를 통해 공격자는 사용자의 권한을 이용하여 악의적인 동작을 수행할 수 있습니다.
CSRF 토큰
을 발급하고 프론트엔드에서 요청 시 해당 Token을 함께 포함하여 전송합니다.이 토큰은 사용자의 세션과 관련하여 생성되며, 공격자는 사용자의 토큰을 알 수 없기 때문에 공격을 실행할 수 없습니다.SameSite
속성을 Strict
또는 Lax
로 설정하여 외부 도메인에서의 요청을 제한할 수 있습니다. 이를 통해 외부 사이트에서 사용자의 인증된 세션을 이용하여 CSRF 공격을 실행하는 것을 방지할 수 있습니다. Referrer
헤더를 검증하여 요청이 유효한 출처에서 왔는지 확인할 수 있습니다. 이를 통해 악의적인 사이트에서의 요청을 거부할 수 있습니다.CORS(Cross-Origin Resource Sharing)
정책을 설정하여 허용할 출처를 명시해야 합니다.💡보충 설명
1. CSRF 토큰: CSRF 토큰은 사용자의 세션과 관련된 임의의 값을 포함한 문자열로 구성되어 있습니다. 일반적으로 웹 애플리케이션은 사용자가 로그인할 때마다 새로운 CSRF 토큰을 생성하고, 이를 사용자의 세션과 연결하여 유지합니다. 이후 사용자가 애플리케이션에서 중요한 동작을 수행할 때마다 CSRF 토큰이 요청과 함께 전송됩니다.
2. SameSite 옵션: SameSite 옵션은 쿠키가 동일 출처 요청에서만 전송되도록 제한하는데 사용되는 옵션입니다. 이 옵션을 설정함으로써 CSRF 공격과 같은 보안 위협으로부터 쿠키를 보호할 수 있습니다. SameSite 옵션에는 아래와 같이 세 가지 값이 있습니다.
- Strict:
SameSite=Strict
를 설정하면 쿠키는 항상 동일 출처 요청에만 포함되며, 외부 도메인으로의 요청에는 포함되지 않습니다.- Lax:
SameSite=Lax
를 설정하면 외부 도메인으로의 GET 요청에는 쿠키가 포함되지만, POST 요청과 외부 도메인으로의 GET 요청에서는 쿠키가 포함되지 않습니다. 이는 사용자의 탐색을 유지하면서 CSRF 공격을 방지합니다.- None:
SameSite=None
을 설정하면 쿠키가 모든 요청에 포함될 수 있습니다. 이 옵션은 HTTPS 연결에서만 사용 가능하며, 외부 도메인으로의 요청에도 쿠키가 포함됩니다. 이 옵션은 규정 준수 브라우저에서만 지원됩니다.2. CORS(Cross-Origin Resource Sharing): 웹 애플리케이션에서 리소스에 대한 교차 출처 요청을 제어하는 보안 메커니즘입니다. 동일 출처 정책(Same-Origin Policy)에 의해 브라우저는 다른 출처의 리소스에 대한 요청을 제한하는데, 이를 극복하기 위해 CORS가 도입되었습니다.
XSS 공격은 악의적인 사용자가 웹 애플리케이션에 스크립트 코드를 삽입하여 다른 사용자들의 브라우저에서 실행되도록 하는 공격입니다. 이를 통해 공격자는 사용자의 세션 쿠키를 탈취하거나 다른 악의적인 동작을 수행할 수 있습니다.
XSS 공격은 주로 사용자 입력값을 안전하게 처리하지 않거나, 외부에서 가져온 데이터를 신뢰하지 않고 출력하는 경우에 발생합니다. 예를 들어, 웹 애플리케이션에서 사용자가 입력한 코멘트를 그대로 HTML에 삽입하거나, 외부 사이트에서 가져온 내용을 동적으로 웹 페이지에 출력하는 경우에 발생할 수 있습니다.
정규표현식
을 사용하여 입력값의 형식을 검사할 수 있습니다. 또는 DOMPurify
와 같은 라이브러리를 사용할 수 있습니다.Content Security Policy(CSP)
를 설정하여 스크립트 실행을 제한하거나 외부 리소스의 로딩을 금지함으로써 XSS 공격을 방지할 수 있습니다.HttpOnly
및 Secure
속성을 설정하여 JavaScript에서 접근할 수 없도록 합니다. (Secure 속성을 설정하게 되면, HTTPS에서만 쿠키 접근 가능)X-XSS-Protection
헤더를 설정하여 브라우저의 내장 XSS 필터를 활성화하거나, X-Content-Type-Options
헤더를 설정하여 브라우저가 MIME 타입을 잘못 해석하는 것을 방지할 수 있습니다.💡보충 설명
- 특수 문자 이스케이프 처리:
- 사용자 입력값에 포함된 특수 문자를 이스케이프 처리하여 해당 문자가 HTML로 해석되지 않도록 합니다.
- 예를 들어,
<
문자를<
,>
문자를>
로 변환하여 HTML 태그로 해석되지 않도록 합니다.- DOMPurify 라이브러리:
- DOMPurify는 XSS 공격으로부터 웹 애플리케이션을 보호하기 위한 라이브러리입니다.
- 사용자 입력값을 안전하게 필터링하고 이스케이프 처리하여 HTML 태그를 제거하거나 비허용된 속성을 제거합니다.
- 또한, DOMPurify는 XSS 필터링 외에도 CSS 인젝션과 같은 다른 보안 문제도 방지합니다. (cf.
CSS 인젝션
: CSS 인젝션은 악의적인 사용자가 웹 애플리케이션에 CSS 코드를 삽입하여 보안 문제를 일으키는 공격입니다. 이러한 공격은 주로 사용자 입력이 웹 페이지에 동적으로 삽입될 때 발생할 수 있습니다.)예를 들어, 사용자가 입력한 내용을 웹 페이지에 출력할 때 다음과 같은 작업을 수행할 수 있습니다:
const userInput = '<script>alert("XSS attack!")</script>'; const sanitizedInput = DOMPurify.sanitize(userInput); document.getElementById('output').innerHTML = sanitizedInput;
위 코드에서는 사용자 입력값을 DOMPurify를 사용하여 필터링하고 안전하게 출력합니다. 사용자가 입력한
<script>
태그는 제거되고, 텍스트로 처리됩니다. 이를 통해 XSS 공격을 방지할 수 있습니다.
CSRF
와 XSS
는 웹 보안 공격의 두 가지 주요 형태로 주요 특징을 정리하자면 아래와 같습니다.
CSRF(Cross-Site Request Forgery):
XSS(Cross-Site Scripting):
따라서 CSRF는 사용자의 권한을 이용하여 악성 요청을 실행하는 반면, XSS는 악성 스크립트를 이용하여 사용자의 브라우저에서 악의적인 동작을 수행하는 것입니다.