CSRF 공격 이해 및 CSRF 취약점 잠금
게시 됨: 2022-11-21웹 취약점은 만연하고 지속적으로 증가하고 있습니다. 사용자의 보안과 개인 정보를 유지하는 것이 그 어느 때보다 중요합니다. 웹 취약점을 해결하지 않으면 평판이 손상되고 규제 기관으로부터 막대한 벌금이 부과될 수 있으며 사용자의 신뢰도 잃게 됩니다.
웹 사이트 및 웹 애플리케이션은 맬웨어, 스팸 및 기타 공격에 취약합니다. 이 기사에서는 이러한 공격 벡터 중 하나인 CSRF(Cross-Site Request Forgery) 공격에 중점을 둡니다. CSRF 공격은 사용자 모르게 발생할 수 있기 때문에 특히 문제가 됩니다. 또한 악의적인 요청은 실제 요청과 매우 유사하게 나타나기 때문에 개발자나 웹사이트 소유자가 감지하기 어렵습니다.
이 기사에서는 CSRF 공격, 작동 방식 및 이에 대비하기 위해 취할 수 있는 단계를 살펴봅니다.
CSRF 공격이란?
CSRF 공격이라고도 하는 교차 사이트 요청 위조 공격은 인증된 사용자가 인식하지 못하는 사이에 악의적인 요청을 제출하여 의도하지 않은 작업을 수행하도록 속입니다.
일반적으로 CSRF 공격에는 공격자가 응답을 받지 못하기 때문에 상태 변경 요청이 포함됩니다. 이러한 요청의 예로는 기록 삭제, 비밀번호 변경, 제품 구매 또는 메시지 전송이 있습니다. 이는 모두 사용자 모르게 발생할 수 있습니다.
악의적인 공격자는 일반적으로 사회 공학을 사용하여 의심하지 않는 사용자에게 채팅이나 이메일을 통해 링크를 보냅니다.
사용자가 링크를 클릭하면 공격자가 설정한 명령을 실행합니다.
예를 들어 링크를 클릭하면 사용자 계정에서 자금을 이체할 수 있습니다. 또는 사용자의 이메일 주소를 변경하여 계정 액세스 권한을 다시 얻지 못하게 할 수 있습니다.
CSRF 공격은 어떻게 작동합니까?
사용자가 로그인한 상태에서 상태 변경 요청을 시작하도록 하는 것은 CSRF 공격의 첫 번째이자 가장 중요한 단계입니다. CSRF 공격을 통해 공격자는 인증된 사용자가 자신도 모르게 웹 사이트 또는 웹 애플리케이션에 악성 웹 요청을 제출하도록 하는 것을 목표로 합니다. 이러한 요청은 쿠키, URL 매개변수 및 사용자에게 정상적으로 표시되는 기타 데이터 유형으로 구성될 수 있습니다.
CSRF 공격이 성공하려면 다음 조건이 발생해야 합니다.
- 인증된 사용자는 세션 관리를 위해 쿠키를 사용하는 웹 애플리케이션에 로그인해야 합니다.
- 공격자는 상태 변경 위조 요청을 생성해야 합니다.
- 대상 서버에서 처리하는 정품 요청에는 예측할 수 없는 매개변수가 포함되어서는 안 됩니다. 예를 들어 요청은 상태 변경 요청을 시작하기 전에 확인 목적을 위한 매개변수로 비밀번호를 기대해서는 안 됩니다.
CSRF 공격을 완료하는 가장 일반적인 방법은 SameSite 쿠키 정책이 약한 애플리케이션에서 쿠키를 사용하는 것입니다. 웹 브라우저는 자동으로 그리고 종종 익명으로 쿠키를 포함하며 사용자가 해당 도메인으로 보내는 모든 웹 요청에서 도메인에서 사용하는 쿠키를 저장합니다.
SameSite 쿠키 정책은 크로스 사이트 브라우징 컨텍스트에서 브라우저가 쿠키를 처리하는 방식을 정의합니다. 엄격하게 설정하면 쿠키가 크로스 사이트 브라우징 컨텍스트에서 공유되지 않아 CSRF 공격을 방지합니다. 없음으로 설정된 경우 브라우저는 모든 교차 사이트 컨텍스트에서 쿠키를 첨부합니다. 이로 인해 응용 프로그램이 CSRF 공격에 취약해집니다.
사용자가 자신도 모르게 웹 브라우저를 통해 악의적인 요청을 제출하면 저장된 쿠키로 인해 해당 요청이 서버에 합법적인 것으로 표시됩니다. 그런 다음 서버는 사용자 계정을 변경하거나 세션 상태를 변경하거나 요청된 데이터를 반환하여 요청에 응답합니다.
CSRF 공격 경로의 두 가지 예를 자세히 살펴보겠습니다. 하나는 GET 요청이고 다른 하나는 POST 요청입니다.
GET 요청에 대한 CSRF
먼저 공격이 GET 요청 및 하이퍼링크 전달을 악용하는 금융 뱅킹 웹 애플리케이션에서 사용하는 GET 요청을 고려하십시오.
송금에 대한 GET 요청이 다음과 같다고 가정합니다.
GET https://xymbank.com/online/transfer?amount=1000&accountNumber=547895 HTTP/1.1
위의 실제 요청에서 사용자는 구매한 제품에 대한 지불로 $1,000를 547895
계정으로 이체하도록 요청합니다.
이 요청은 명시적이고 간단하며 실용적이지만 계정 소유자를 CSRF 공격에 노출시킵니다. 요청에 공격자가 모를 수도 있는 세부 정보가 필요하지 않기 때문입니다. 따라서 공격을 시작하기 위해 공격자는 실행 가능한 위조 요청을 생성하기 위해 이 요청의 매개변수(금액 및 계정 번호)를 변경하기만 하면 됩니다.
악의적인 요청은 쿠키 관리 세션이 진행 중인 한 모든 은행 사용자에게 유효합니다.
$500를 해커의 계정(여기서는 번호 654585
)으로 전송하라는 위조된 요청은 다음과 같습니다. 아래 예제는 설명을 위해 CSRF 공격과 관련된 단계를 매우 단순화한 버전입니다.
GET https://xymbank.com/online/transfer?amount=500&accountNumber=654585 HTTP/1.1
완료되면 공격자는 사용자가 온라인 뱅킹 애플리케이션에 로그인되어 있는 동안 이 요청을 보내도록 속이는 방법을 찾아야 합니다. 이를 수행하는 방법 중 하나는 사용자의 주의를 끄는 무해한 하이퍼링크를 만드는 것입니다. 링크는 다음과 같을 수 있습니다.
<a href="https://xymbank.com/online/transfer?amount=500&accountNumber=654585">Click here to get more information</a>.
공격자가 대상의 올바른 이메일 주소를 찾았다면 이를 이메일을 통해 많은 은행 고객에게 보낼 수 있습니다. 로그인한 상태에서 링크를 클릭하면 로그인된 계정에서 공격자에게 $500를 보내라는 요청이 트리거됩니다.
POST 요청에 대한 CSRF
동일한 금융 기관이 POST 요청만 수락한 경우 CSRF가 어떻게 발생하는지 살펴보겠습니다. 이 경우 GET 요청 예제에 사용된 하이퍼링크 전달이 작동하지 않습니다. 따라서 CSRF 공격이 성공하려면 공격자가 HTML 양식을 생성해야 합니다. 구매한 제품에 대해 $1,000를 보내라는 실제 요청은 다음과 같습니다.
POST /online/transfer HTTP/1.1 Host: xymbank.com Content-Type: application/x-www-form-urlencoded Cookie: session=FRyhityeQkAPzeQ5gHgTvlyxHJYhg amount=1000 account=547895
이 POST 요청에는 사용자의 신원, 전송하려는 금액 및 전송하려는 계정을 결정하는 쿠키가 필요합니다. 공격자는 이 요청을 변경하여 CSRF 공격을 수행할 수 있습니다.
공격자는 서버가 전송을 처리하도록 위조된 요청에 정품 쿠키만 추가해야 합니다. 그들은 사용자를 다음과 같은 트리거 웹 페이지로 안내하는 무해한 모양의 하이퍼링크를 만들어 이를 수행할 수 있습니다.
<html> <body> <form action="https://xymbank.com/online/transfer" method="POST"> <input type="hidden" name="amount" value="500"/> <input type="hidden" name="account" value="654585" /> </form> <script> document.forms[0].submit(); </script> </body> </html>
우리는 이미 위의 양식에 금액 및 계정 매개변수를 설정했습니다. 인증된 사용자가 페이지를 방문하면 브라우저는 요청을 서버에 전달하기 전에 세션 쿠키를 추가합니다. 그런 다음 서버는 $500를 해커의 계정으로 전달합니다.
CSRF 공격을 완화하는 3가지 방법
웹 사이트 또는 웹 애플리케이션에 대한 잠재적인 CSRF 공격을 방지하고 대폭 완화하는 방법에는 다음과 같은 몇 가지 방법이 있습니다.
- CSRF 토큰 사용
- 리퍼러 헤더 사용
- Kinsta와 같은 보안 중심 호스팅 솔루션 선택
CSRF 토큰을 사용하여 CSRF 공격을 방지하는 방법
CSRF 보안 웹 사이트는 각 세션에 고유한 토큰을 할당하고 서버 측 및 클라이언트 브라우저와 공유합니다. 브라우저가 중요한 요청을 보낼 때마다 서버는 할당된 CSRF 토큰을 포함할 것으로 예상합니다. 잘못된 토큰이 있는 경우 서버는 토큰을 삭제합니다. CSRF 토큰은 보안을 위해 클라이언트 브라우저의 세션 쿠키에 저장되지 않습니다.
CSRF 토큰의 잠재적인 취약점
CSRF 토큰은 뛰어난 보안 수단이지만 이 방법은 공격을 방지할 수 없습니다. CSRF 토큰에 수반되는 일부 취약점은 다음과 같습니다.
- 유효성 검사 우회 — 일부 애플리케이션은 토큰을 찾지 못하면 확인 단계를 건너뜁니다. 공격자가 토큰이 포함된 코드에 대한 액세스 권한을 얻으면 해당 토큰을 제거하고 CSRF 공격을 성공적으로 실행할 수 있습니다. 따라서 서버에 대한 유효한 요청이 다음과 같은 경우:
POST /change_password POST body: password=pass123&csrf_token=93j9d8eckke20d433
공격자는 공격을 실행하기 위해 토큰을 제거하고 다음과 같이 보내기만 하면 됩니다.
POST /change_password POST body: password=pass123
- 풀링된 토큰 — 일부 애플리케이션은 세션에 특정 토큰을 지정하는 대신 사용자 세션의 유효성을 검사하기 위해 토큰 풀을 유지합니다. 공격자는 사이트의 사용자를 가장하기 위해 이미 풀에 있는 토큰 중 하나만 얻으면 됩니다.
공격자는 자신의 계정을 사용하여 애플리케이션에 로그인하여 다음과 같은 토큰을 얻을 수 있습니다.
[application_url].com?csrf_token=93j9d8eckke20d433
그리고 토큰이 풀링되기 때문에 공격자는 동일한 토큰을 복사하여 다른 사용자 계정에 로그인하는 데 사용할 수 있습니다.
- CSRF는 쿠키에 토큰 복사 가능 — 일부 애플리케이션은 토큰과 관련된 매개변수를 사용자 쿠키에 복사합니다. 공격자가 이러한 쿠키에 대한 액세스 권한을 얻으면 쉽게 다른 쿠키를 만들어 브라우저에 배치하고 CSRF 공격을 실행할 수 있습니다.
따라서 공격자는 자신의 계정을 사용하여 애플리케이션에 로그인하고 쿠키 파일을 열어 다음을 볼 수 있습니다.
Csrf_token:93j9d8eckke20d433
그런 다음 이 정보를 사용하여 다른 쿠키를 만들어 공격을 완료할 수 있습니다.
- 유효하지 않은 토큰 — 일부 애플리케이션은 CSRF 토큰을 사용자 세션과 일치시키지 않습니다. 이러한 경우 공격자는 진정으로 세션에 로그인하고 위와 유사한 CSRF 토큰을 획득하고 이를 사용하여 피해자의 세션에서 CSRF 공격을 조율할 수 있습니다.
리퍼러 헤더로 CSRF 공격을 방지하는 방법
CSRF 공격을 방지하기 위한 또 다른 전략은 리퍼러 헤더를 사용하는 것입니다. HTTP에서 리퍼러 헤더는 요청의 출처를 나타냅니다. 일반적으로 분석, 최적화 및 로깅을 수행하는 데 사용됩니다.
CSRF 공격을 방지하기 위해 서버 측에서 리퍼러 헤더 확인을 활성화할 수도 있습니다. 서버 측은 요청의 소스 출처를 확인하고 요청의 대상 출처를 결정합니다. 일치하면 요청이 허용됩니다. 일치하지 않는 경우 서버는 요청을 삭제합니다.
리퍼러 헤더를 사용하는 것은 개별 사용자 식별이 필요하지 않기 때문에 토큰을 사용하는 것보다 훨씬 쉽습니다.
리퍼러 헤더의 잠재적인 취약점
CSRF 토큰과 마찬가지로 리퍼러 헤더에는 몇 가지 중요한 취약점이 있습니다.
첫째, 리퍼러 헤더는 필수가 아니며 일부 사이트에서는 리퍼러 헤더 없이 요청을 보냅니다. CSRF에 헤더 없이 요청을 처리하는 정책이 없는 경우 공격자는 헤더 없는 요청을 사용하여 상태 변경 공격을 실행할 수 있습니다.
또한 이 방법은 최근 리퍼러 정책이 도입되면서 효율성이 떨어졌습니다. 이 사양은 URL이 다른 도메인으로 유출되는 것을 방지하여 사용자가 리퍼러 헤더의 정보를 더 잘 제어할 수 있도록 합니다. 아래와 같이 HTML 페이지에 메타데이터 태그를 추가하여 리퍼러 헤더 정보의 일부를 노출하거나 비활성화하도록 선택할 수 있습니다.
<meta name="referrer" content="no-referrer">
위의 코드는 이 페이지의 모든 요청에 대한 리퍼러 헤더를 제거합니다. 이렇게 하면 리퍼러 헤더에 의존하는 애플리케이션이 해당 페이지에서 CSRF 공격을 방지하기가 어렵습니다.
Kinsta가 CSRF 공격으로부터 보호하는 방법
리퍼러 헤더와 CSRF 토큰을 사용하는 것 외에도 세 번째이자 더 쉬운 옵션이 있습니다. 웹 사이트 및 웹 애플리케이션에 Kinsta와 같은 보안 호스팅 서비스를 선택하면 공격자와 사용자 사이에 훨씬 더 강력하고 안전한 장벽이 제공됩니다.
자동 백업, 2단계 인증, SSH 프로토콜을 통한 SFTP와 같은 중요한 보안 기능 외에도 Kinsta의 Cloudflare 통합은 IP 기반 및 방화벽 보호와 함께 엔터프라이즈급 보호를 제공합니다.
특히 Kinsta는 현재 악의적인 공격을 방지하고 CSRF 취약성을 찾는 특정 항목을 포함하여 플러그인 및 테마의 인증되지 않은 심각한 취약성을 처리하는 데 도움이 되는 약 60개의 사용자 지정 방화벽 규칙을 보유하고 있습니다.
요약
CSRF(교차 사이트 요청 위조)는 인증된 사용자를 속여 의도치 않게 상태 변경 요청을 시작하도록 하는 공격입니다. 유효한 요청과 위조된 상태 변경 요청을 구분할 수 없는 애플리케이션을 대상으로 합니다.
CSRF는 세션 쿠키에 의존하여 로그인한 사용자를 식별하고 SameSite 쿠키 정책이 약한 애플리케이션에서만 성공할 수 있습니다. 또한 암호와 같은 알 수 없는 매개 변수가 포함되지 않은 요청을 수락하는 서버도 필요합니다. 해커는 GET 또는 POST를 사용하여 악의적인 공격을 보낼 수 있습니다.
CSRF 토큰을 사용하거나 리퍼러 헤더 확인을 시행하면 일부 CSRF 공격을 방지할 수 있지만 두 가지 조치 모두 조심하지 않으면 예방 조치를 쓸모없게 만들 수 있는 잠재적인 취약점이 있습니다.
Kinsta와 같은 안전한 호스팅 플랫폼으로 마이그레이션하면 CSRF 공격으로부터 웹 사이트 또는 웹 앱을 보호할 수 있습니다. 또한 Kinsta와 Cloudflare의 통합은 특정 CSRF 공격을 방지합니다.