#[Spring] Google reCAPTCHA v3

 

 

오늘은 자동화 공격에 대한

구글이 제공하는 reCAPTCHA에 대해 소개하려 한다.

reCAPTCHA는 자동화 공격을 막기 위한 방법으로

흔히들 아는 "로봇이 아닙니다"를 떠올이면 된다.

자동화 공격은 사람이 아닌 기계로 공격을 하는 것으로

매크로를 만들어 불법적인 프로그램을 사용하거나

로그인을 할 때 비밀번호를 기계가 자동으로 입력하여

계정을 해킹하는 것 등을 말한다.

Google reCAPTCHA v2는

의심스러운 트래픽이 발생하면

'로봇이 아닙니다'를 증명하기 위해

사람만이 판단할 수 있는 이미지를 클릭하는 방식으로 방어하는 방식이다.

하지만 v2 방식은 이용자들에게 불편함을 주는 방식으로

이미지를 클릭해도 다른 이미지가 나와 여러번 클릭하거나

로그인할 때마다 로봇이 아니라는 것을 인증해야 해서

빡친 사람은 나뿐만이 아닐 것이다.

속사정은 모르지만

아마도 사용자를 방해한다는 피드백이 있어

reCAPTCHA v3가 나온 것이 아닐까 추측한다.

reCAPTCHA v3는 v2와 다르게 사용자를 방해하지 않는다.

사용자의 행동(action)을 보고 기계인지 사람인지 판단하는 방법이다.

reCAPTCHA v3는 0 ~ 1.0 까지의 점수를 서버에 보내주는데

0에 가까울수록 기계에 가깝다는 뜻이고

1에 가까울수록 사람에 가깝다고 알려준다.

간단하게 reCAPTCHA v3를 한번 구현해보자.

먼저, Google reCAPTCHA 사이트에 들어가 admin console 사이트를 등록한다.

https://www.google.com/recaptcha/intro/v3.html

 

v3 유형을 선택하고

도메인은 test용이니 localhost를 등록한다.

완료가 되면 사이트 키와 비밀 키를 받는데

설정에서 그 내용을 확인할 수 있다.

그 다음

Spring으로 간단한 maven 프로젝트를 생성한다.

recaptcha.jsp 파일은 다음과 같이 작성하였다.

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<html>

<head>
    <meta charset="UTF-8">
    <title>구글 리캡챠 테스트</title>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
    <script src="https://www.google.com/recaptcha/api.js?render=6Le-q6kUAAAAAFPDTU6lct7ZRRN7vK55hVF4Icp3"></script>
</head>

<body>
    <form action="/robot" method="get">
        <input type="text" name="name" />
        <input type="text" name="g-recaptcha-response" id="g-recaptcha-response" />
        <input type="submit" value="submit" />
    </form>

<script>
$(document).ready(function(){
    grecaptcha.ready(function() {
      grecaptcha.execute('reCAPTCHA_site_key', {action: 'login'}).then(function(token) {
         console.log(token)
         $.ajax({
            url: '${pageContext.servletContext.contextPath}/robot/token',
            type : 'POST',
            dataType: 'json',
            data : {'token': token},
            success : function(result){
                console.log(result);
            },
            fail: function(e){
                console.log("fail")
            }
          });// end ajax
      });
    });
});
</script>
</body>

</html>

Google DreCAPTCHA_site_key에 할당받은 사이트 키를 넣고

서버와 ajax 통신을 위해 jQuery를 이용했다.

일단 이 상태에서 토큰이 다음처럼 받아져야 한다.

이제 Controller에서 받아 Service 단에서 google reCAPTCHA와 통신을 한다.

통신 방법은 RestTemplate을 사용했으며

Post방식으로 토큰과 비밀키 값을 전송한다.

@Service
public class RecaptchaService {

    public RecaptchaDTO token(String token) {
        String url = "https://www.google.com/recaptcha/api/siteverify";

        RestTemplate restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
        map.add("secret", "secret-key");
        map.add("response", token);

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);

        RecaptchaDTO response = restTemplate.postForObject( url, request, RecaptchaDTO.class );

        return response;
    }

}

받은 자료를 콘솔에 뿌려주면 다음처럼 나오게 될 것이다.

여기서 score를 보면 0.9라는 것을 볼 수 있다.

이는 reCAPTCHA가 사람에 가깝다는 것을 판단한 것이며

이 score를 이용하여 서비스의 동작을 통제하면 될 것이다.

참고자료

https://developers-kr.googleblog.com/2019/01/introducing-recaptcha-v3-new-way-to.html

https://dany-it.tistory.com/302

https://developers.google.com/recaptcha/docs/v3?hl=ko

 

 

Made by 꿩

'IT > 보안' 카테고리의 다른 글

[방화벽] 인바운드 & 아웃바운드  (0) 2022.01.31
OAuth  (0) 2019.06.17
SSL인증서  (0) 2019.03.21
CSRF  (0) 2018.12.25
XSS 공격과 방어  (2) 2018.10.25

+ Recent posts