CSRF (Cross-Site Request Forgery) 공격은 크로스 사이트 요청 위조로 지속적으로 웹 애플리케이션을 위협하는 보안 취약점 중 하나로 공격자가 사용자의 인증 정보를 악용하여 의도하지 않은 요청을 서버에 보내는 방식입니다
CSRF는 사용자가 신뢰하는 웹 사이트에 인증된 상태에서 공격자가 악의적인 요청을 하도록 유도해 사용자의 권한으로 특정 작업을 실행시키는 것이 핵심입니다
단순한 정보 유출만이 아닌 악성 스크립트를 통한 사용자의 쿠키 값, 세션 정보를 특정 사이트로 이동시키는 등의 행위를 포함합니다
이 공격은 사용자가 인증한 세션에서 웹 애플리케이션이 정상적인 요청과 비정상적인 요청을 구분하지 못하는 점을 악용하는 공격 방식입니다
특히 사용자의 요청이 실제 사용자가 전송한 것인지 확인하지 않는 경우 자주 발생하게 됩니다
CSRF의 공격이 성공하기 위해서는 특정 조건들이 만족되어야 합니다
사용자 인증 상태: 사용자는 공격 대상의 웹사이트에 이미 로그인되어 있는 상태여야 합니다
쿠키 기반 세션: 쿠키를 통해 서버 세션 정보를 획득할 수 있어야 합니다
요청 방법 파악: 공격자는 서버를 공격하기 위한 요청 방법을 미리 파악하고 있어야 합니다
예상치 못한 파라미터 부재: 공격자가 예측하지 못하는 요청 매개변수가 없어야 합니다
CSRF 공격의 주요 단계는 다음과 같습니다
CSRF 공격은 다양한 경로를 통해 실행될 수 있습니다
공격자는 희생자에게 악성 링크가 포함된 이메일을 보냅니다
예를 들어 전 글의 XSS 실습 때 처럼 긴급 메일인 것 처럼 메일에 악성 코드를 삽입하여 클릭하도록 유도합니다
공격자는 사용자를 속여 악성 코드가 포함된 웹사이트로 이동하게 합니다
사용자가 특정 웹사이트에 로그인한 상태에서 공격자의 웹사이트를 방문하면, 공격자의 웹사이트는 사용자 몰래 사용자가 로그인한 사이트로 악의적인 요청을 보냅니다
피싱 (Phishing은 사용자를 속여 개인정보나 금융 정보 등을 탈취하려는 사회공학적 공격 방식입니다
공격자는 피싱 사이트를 만들고 사용자가 이 사이트에 접속하면 자동으로 악성 요청이 전송됩니다
피싱 사이트 접속을 유도하기 위해 피싱 메일, 팝업 광고 등을 활용합니다
CSRF 공격 스크립트를 대상 사이트에 저장하는 방식입니다
HTML 코드의 IMG 파일이나 iframe 태그에 CSRF 공격 코드를 포함시켜 사용자가 해당 페이지를 방문할 때 자동으로 실행되게 합니다
이는 XSS 취약점과 결합하여 더 위험해질 수 있습니다
CSRF 공격은 여러 방식으로 이루어질 수 있으며 주요 유형은 다음과 같습니다
GET 방식은 URL을 통해 데이터를 전달하는 방식으로 단순히 URL을 변형하는 것만으로도 공격이 가능합니다
아래는 간단한 예시입니다
<img src="http://examplesite/user/logout" width="0" height="0">
위 코드는 사용자를 강제로 로그아웃시키는 CSRF 공격 예시입니다
이미지 태그는 GET 요청을 사용하기 때문에 페이지가 로드되는 순간 해당 URL로 요청이 전송됩니다
POST 방식은 단독으로 사용은 어려우며 주로 XSS와 결합하여 사용됩니다
form 태그를 사용하여 자동으로 요청을 전송하는 방식입니다
아래는 간단한 예시입니다
<form method="POST" action="http://target.com/change_password">
<input type="hidden" name="new_password" value="hackerpw">
</form>
<script>document.forms[0].submit();</script>
이 코드가 XSS 취약점을 통해 웹페이지에 삽입되면 사용자가 페이지를 방문하는 순간 패스워드 변경 요청이 자동으로 전송됩니다
Ajax 등 비동기 HTTP 요청을 처리하는 JavaScript를 속여 원래 의도되지 않은 기능을 수행하는 형태입니다
아래는 간단한 예시입니다
<script>
fetch("https://bank.com/api/transfer", {
method: "POST",
credentials: "include",
body: JSON.stringify({ to: "attacker", amount: 1000000 }),
headers: {
"Content-Type": "application/json"
}
});
</script>
위 코드가 삽입된 페이지를 사용자가 열면 사용자의 쿠키가 자동으로 전송되고 서버는 정상 사용자의 요청으로 처리를 합니다
CSRF와 XSS 취약점이 결합되면 더 강력한 공격이 가능합니다
XSS를 통해 악성 스크립트를 삽입하고 이 스크립트가 CSRF 공격을 수행하는 방식입니다
이는 기본적인 CSRF 방어를 우회할 수 있습니다
아래는 간단한 예시입니다
<script>
fetch("https://bank.com/api/transfer", {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
to: "attacker_account",
amount: 1000000
})
});
</script>이 스크립트는 사용자가 해당 게시글을 보기만 해도 자동으로 실행됩니다CSRF 공격을 방어하기 위한 다양한 기법들은 다음과 같습니다
가장 효과적인 CSRF 방어 방법으로, 각 요청마다 서버가 난수로 생성된 토큰을 포함시켜 요청의 정당성을 확인합니다
CSRF 토큰은 웹 애플리케이션에서 사용자 세션을 보호하는 데 사용되는 무작위로 생성된 고유한 값입니다
이 토큰은 사용자의 브라우저에 저장되며 요청마다 서버에 전송됩니다
쉽게 크랙할 수 없는 긴 길이의 토큰을 사용해야 합니다
토큰은 추적, 역분석이 어려워야 합니다
기능 페이지 요청 시마다 새로 발급하고, 사용된 토큰을 폐기처리하는 것이 좋습니다
각 유저 세션당 고유한 토큰이어야 합니다
토큰은 HTTP Header, URI, Body 등으로 전달하고 쿠키로는 전달하지 않는 것이 안전합니다
요청의 Referer 헤더를 검토하여 요청이 올바른 출처에서 발생했는지 확인하는 방법입니다
eferer 헤더는 현재 요청된 페이지의 링크 이전의 웹페이지 주소를 포함하므로, 이를 통해 요청이 정당한 곳에서 왔는지 검증할 수 있습니다
하지만 동일 사이트 내에서 XSS 취약점이 발견될 시 이를 통해 CSRF 공격이 가능할 수 있으므로 페이지 단위까지 도메인 검증을 하는 것이 좋습니다
쿠키에 SameSite 속성을 설정하여 같은 도메인에서만 쿠키가 전송되도록 제한하는 방법입니다
SameSite 쿠키는 다음과 같은 값을 가질 수 있습니다
Strict: 쿠키는 오직 같은 사이트 출처의 요청에서만 전송됩니다Lax: Strict와 유사하지만, 사용자가 쿠키 출처 사이트로 이동할 때도 쿠키를 전송합니다None: 쿠키는 원본 및 크로스 사이트 요청 모두에 전송됩니다 (Secure 속성도 필요)가능한 가장 강력한 SameSite 수준을 설정하는 것이 좋으며, 특별한 이유가 없다면 None으로 설정하지 않는 것이 좋습니다
웹브라우저의 Same Origin 정책으로 인해 자바스크립트에서 타 도메인의 쿠키값을 확인, 수정하지 못한다는 특성을 이용한 방어 기법입니다
요청 시 난수를 생성하여 쿠키에 저장하고, 동일한 난수 값을 요청 파라미터에 포함시켜 서버에 전송합니다
서버는 쿠키의 토큰 값과 파라미터의 토큰 값이 일치하는지만 검사하면 됩니다
이 방법은 서버에 토큰값을 저장할 필요가 없어 세션 검증보다 가벼운 장점이 있습니다
이미지를 보여주고 그에 해당하는 문자/숫자/그림을 맞춰야 요청을 승인하는 CAPTCHA는 CSRF 공격을 효과적으로 방어할 수 있는 방법입니다
이는 자동화된 요청을 방지하고 사용자의 실제 의도를 확인할 수 있게 해줍니다
GET 방식은 URL 변경만으로도 데이터 변경이 가능한 반면, POST 방식은 스크립트가 필요합니다
GET 방식보다 POST 방식이 변조하기 어렵기 때문에, 중요한 기능은 GET 대신 POST 방식을 사용하는 것이 좋습니다
중요한 작업 수행 시 추가 인증 정보를 요구하는 방법입니다
예를 들어, 비밀번호 변경 시 현재 비밀번호를 입력해야만 변경이 가능하도록 하는 것입니다
공격자는 이전 비밀번호를 알기 어렵기 때문에 CSRF 공격을 어렵게 만듭니다
OTP (One-Time Password)와 같은 추가 인증 수단도 효과적인 방어 방법입니다
CSRF와 XSS는 모두 웹 보안 취약점이지만 명확한 차이가 있습니다
XSS는 공격자가 웹 페이지에 악성 스크립트 (JavaScript 등)를 삽입하고, 이 스크립트가 사용자의 브라우저에서 실행되도록 유도하는 공격입니다 브라우저가 스크립트를 자동 실행하면서 보안 문제가 발생합니다
CSRF는 정상적인 사용자가 공격자 의도대로 특정 서버에 요청을 보내도록 만드는 공격입니다
사용자가 로그인된 상태를 악용해 브라우저의 자동 쿠키 전송 기능을 이용하여, 서버가 요청을 신뢰하도록 속이는 것입니다
즉 XSS는 사용자에게 직접적인 해를 끼치는 공격이고, CSRF는 사용자의 세션을 빌려 서버에 해를 끼치는 공격이라고 볼 수 있습니다
이번에는 간단하게 CSRF에 대해 알아봤습니다
찾아보면서 이거 XSS와 연계될 수 있겠다라는 생각을 했는데 확실히 연관된 정보가 많았던 것 같습니다
아직까지 기초적인 웹 해킹 기법에 대해 배우고 있지만 공격들이 전부 위험한 것 같습니다
그래서 배우다보니 확실히 더 보안에 신경을 쓰게되는 것 같습니다
CSRF 실습도 기대가 됩니다!