brunch

You can make anything
by writing

C.S.Lewis

by 테크유람 Mar 28. 2021

자바스크립트 Challenge를
사용한 봇 트래픽 방어

브라우저 특성을 이용하여 봇 트래픽(bot traffic) 필터링하기

JavaScript Challenge란 웹사이트에 접속하는 클라이언트 중 실제 사람에 의한 올바른 접근과 봇(bot), 자동화된 에이전트, 혹은 해킹 도구를 통한 악의적인 접근을 구분하기 위해 JavaScript를 사용하는 방법입니다.


여기서 Challenge를 해석하자면 "도전 과제"
혹은 "과제" 정도가 알맞겠습니다.


접속자에게 일종의 도전 과제가 포함된 자바스크립트 코드를 보내면 통상적으로 자바스크립트를 지원하는 브라우저는 이를 이해하고 올바른 응답을 전달하지만, 봇, 해킹 도구, DDoS 도구 등은 자바스크립트를 해석할 수 없으므로, 도전 과제를 통과할 수 없고 이에 따라 웹 사이트 접근이 금지됩니다.


Cloudflare(클라우드플레어)로 JavaScript Challenge를 적용한 웹 페이지에 접속해보았습니다.

문서의 타이틀은 "Just a moment..."로 보이면서 브라우저를 확인 중이라고 나오죠.


이 과정을 Chrome - 개발자 도구 - 네트워크 탭에서 확인해 보았습니다.


1. 접속한 페이지 URL은 503 에러가 발생합니다. 

2. 원본 서버에는 없는 v1이라는 JS 파일을 Cloudflare로부터 받았습니다. 이 파일은 난독화가 되어있어서 육안으로는 해석이 불가능합니다.


3. 원본 서버에는 없는 gif 이미지 2개를 Cloudflare로부터 받았습니다.

4. favicon 파일로 일단은 503 응답.

5. ~ 무언가 난수로 이루어진 경로들을 호출. 역시 원본 서버에는 없는 파일들이며 Cloudflare가 전달. 이 과정에서 v1에서 받은 JS 파일의 응답을 검증하면서 유효한 브라우저인지를 확인하는 과정으로 보입니다.

6. 비로소 원하는 페이지로 접속.

7. 유효한 브라우저임이 확인되었기에 다시 재접속하면 1~5 과정은 생략됨.


동일한 사이트를 curl 명령으로 접속해보았습니다. 당연한 결과이지만 503 응답으로 끝납니다.

* Connection state changed (MAX_CONCURRENT_STREAMS == 256)!
< HTTP/2 503
< date: Wed, 10 Mar 2021 16:26:23 GMT
< content-type: text/html; charset=UTF-8
....
< x-frame-options: SAMEORIGIN
< cache-control: private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< expires: Thu, 01 Jan 1970 00:00:01 GMT
....
< expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=d3O36U6AY0un%2FW....A%3D%3D"}],"max_age":604800,"group":"cf-nel"}
< nel: {"max_age":604800,"report_to":"cf-nel"}
< server: cloudflare
< alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400


정말 사람인지 확인하기 위해 CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart)를 사용하는 방법도 있죠.






브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari