최근 수정 시각 : 2024-10-12 19:45:59

CSRF

CSRF 방지 토큰에서 넘어옴
1. 개요2. 과정
2.1. 예시
3. 예방4. 나무위키 편집 오류

1. 개요

Cross-Site Request Forgery

사이트 간 요청 위조의 줄임말.

웹 애플리케이션 취약점 중 하나로 사용자가 자신의 의지와 무관하게 공격자가 의도한 행동을 해서 특정 웹 페이지를 보안에 취약하게 한다거나 수정, 삭제 등의 작업을 하게 만드는 공격 방법이다. 2008년에 발생한 옥션개인 정보 유출 사건에서도 관리자 계정을 탈취하는 데 이 방법이 사용되었다. 공격의 난이도가 높지 않아 흔히 사용된다.

2. 과정

이러한 공격을 하기 위해 해커는 우선 공격을 할 사이트를 먼저 분석한다. 예를 들어서 나무위키의 토론 주소는 한때 'namu.wiki/topic/'으로 시작하며 뒤에 토론 개설 순서대로 붙는 일련번호가 붙는 형식으로 되어 있었다.[1] 즉 이 패턴을 이용하여 일반적인 방법으로 접근할 수 없는 페이지를 오픈한다든지, 개발에 사용되고 실제로 사용하지 않는 샘플 페이지를 찾아낸다든지 등의 행위가 가능하다.

웹 페이지가 독자적 개발이 아닌 외부에서 이미 개발된 웹 애플리케이션을 사서 조금 수정한 것이라면 공격자는 경우에 따라서 해당 웹 애플리케이션의 소스 코드를 분석하여 공격 가능 패턴을 찾아낸다. 주로 공격자들이 찾는 것은 사용자 패스워드 변경 페이지나 타 시스템과 로그인 연동 주소 패턴 같은 인증 관련된 취약점을 찾는다.

그다음에 여기서 나온 취약점을 이용해서 공개된 게시판이나 메일을 이용해서 사용자가 해당 링크를 열게 만들면 공격이 완료된다.

2.1. 예시

만일, A라는 사이트의 사용자 개인 비밀번호 변경을 하는 주소 패턴이 'http://example.com/user.do?cmd=user_passwd_change&user=admin&newPwd=1234'[2]라고 한다면 이러한 링크를 사용자의 메일로 보내는데, 만약 사용자가 메일을 읽게 되면[3] 해당 사용자의 패스워드가 1234로 초기화된다. 이를 관리자에게 보내서 일반 계정을 관리자 계정으로 바꾸도록 하거나, 관리자 계정 패스워드를 바꾸는 데 이용한다면 해당 사이트의 모든 정보가 해킹당하는 데는 오랜 시간이 걸리지 않는다.

참고로, img 태그도 GET 메소드를 사용해서 보내는 것이기 때문에 img를 이용할 수도 있다. 대부분의 사이트는 img를 필터링하지 않으므로, 혹은 필터링하지 못하므로 유용한 방법이 될 수 있다.

예를 들면 나무위키의 경우 https://namu.wiki/member/logout와 같은 코드를 넣어주면 해당 문서를 볼 경우 로그아웃이 된다. 이는 나무위키뿐만이 아닌 대부분의 사이트의 문제.[4]

3. 예방

방어 방법 중 가장 기초적인 방법은 Referer 체크를 하는 방법이 있다. Referer는 HTTP 헤더에 있는 정보로 해당 요청이 요청된 페이지의 정보를 가지고 있는데 해당 정보는 Paros나 Zap, fiddler같은 프로그램으로 조작이 가능하기 때문에 권장되지 않는다.
그 외에는 패스워드 변경 같은 민감한 정보를 다룰 때에는 세션에 임의 난수(토큰)를 발급해서, 해당 난수가 없는 상황에서 해당 동작들이 이루어지면 요청을 거부하는 방법을 통하여 사용자가 정말로 변경을 의도하는 경우에만 변경을 시켜주는 방법, 변경 시에 CAPTCHA를 이용하여 CAPTCHA 인증 코드가 없거나 틀리면 거부하도록 하는 방법 등이 이용되고 있다.

또한 GET/POST 등을 구분하여 주는 것 역시 유용하다.[5] img 태그 등을 이용할 경우 GET 요청으로 들어오게 될 것이고, 반면 흔히 하듯 form을 이용해 값을 받을 경우 POST를 이용하게 되는 경우가 많기 때문이다.

위의 방법들을 일일이 적용하기 귀찮다면, 대개 프레임워크에서 위의 방법들을 통합한 플러그인 등을 제공하는 경우들이 많으니 찾아보도록 하자. 또한 form 대신 ajax[6]를 통한 JSON API만 사용하는 방법이 있다. 만약 굳이 다른 도메인 간 통신을 하고자 한다면, jsonp를 이용하면 된다.

파이어폭스 버그질라

4. 나무위키 편집 오류

[오류!] CSRF 방지 토큰이 일치하지 않습니다. 다시 시도해주세요.
[7]

나무위키에서는 편집 시도와 같은 폼 전송이 필요한 작업을 하는 경우 CSRF 토큰이라는 이용자별 고유한 값을 만들어낸다. 이후 폼 전송 시 같이 전송되는 CSRF 토큰이 발급해 뒀던 토큰과 일치하지 않는 경우 오류를 발생시킨다. 주로 편집창을 띄운 채 장시간 방치하거나[8], 인터넷이 재연결되거나, 편집창을 띄운 후 다른 탭에서 편집창을 띄우면 발생된다.

오류가 발생하면 수정 중이던 문서 내용은 보존되므로 그냥 다시 한번 저장을 클릭하면 된다. 다만 간혹 그사이 다른 사용자의 편집이 이루어진 경우 충돌이 발생하여 수동으로 내용을 병합해야 하는 경우도 있다. 다만 새 문서를 생성하거나 문서 이동을 하는 경우 저장 버튼을 여러 번 눌러도 반영되지 않으므로, 그동안 작성한 내용을 복사하고 새 편집창을 다시 열어 붙여넣기를 해야 한다. 그래도 다행히 예전과 다르게 업데이트가 된 건지 모르지만 새 문서나 문서 이동을 하는 경우에도 그냥 다시 한번 저장을 클릭하게 반영이 됐다.


[1] 2019년 12월경 엔진 업데이트로 패턴을 예측할 수 없게 namu.wiki/thread/ 뒤에 라틴 문자로 이루어진 랜덤 문자열이 붙도록 수정되었다.[2] 당연히 현실에서는 어느 사이트도 비밀번호 변경 등의 요청을 GET으로 처리하지 않는다. POST method를 사용하는 요청을 위조하려면 더욱 복잡한 기법이 필요할 것이다.[3] 정확히는 메일을 읽는 것뿐 아니라 로그인할 때 사용한 쿠키가 그대로 남아있는 브라우저로 받은 링크를 클릭해야 할 것이다.[4] HTML 편집을 한 후 바로 로그아웃이 되는 것은 아니고 새로고침을 해야 한다.[5] 자체적으로 환경 변수 전역화를 하는 제로보드, 그누보드 기반 사이트는 이 방법을 쓸 수 없다.[6] CORS가 비활성화되어 있어야 한다.[7] 최초 형태는 'XSS 방지 토큰이 일치하지 않습니다.\'였다.[8] 서버에서 토큰값이 사라진 경우.

분류