숨겨진 이미지 찾기 이벤트에서 사용자 Cheating 방지하기: SHA-256으로 안전하게!
복주머니 이벤트를 열었다
설날을 맞이 하여 사이트에서 복주머니 이벤트를 열었다. 사이트 곳곳에 복주머니 이미지를 꽁꽁 숨겨두고 그 이미지를 누르면 복주머니가 하나씩 하나씩 쌓이는 이벤트이다! 실제로 데모로 내부적으로 진행해 보았을때도 사람들의 반응이 어마무시하게 좋았고 성공적인 이벤트가 될거 같았다!
처음 개발 계획은 다음과 같았다.
1
<img src="복주머니" class="lucky-bag" title="lucky-bag-1"></img>
위의 element 를 click 하면 js에서 lucky endpoint로 요청을 보내주고
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$(".lucky-bag").click(function () {
let title = $(this).attr('title');
$.ajax({
url: '/lucky',
type: 'POST',
data: { luckyBag: title },
success: function(response) {
alert("복주머니를 " + response.count + "개 찾았습니다!")
},
error: function(xhr, status, error) {
}
});
})
spring 에서는 해당 요청이 들어오면 lucky-bag-1 부터 30 사이 인지 확인하고 return 하여줬다
1
2
3
4
5
6
7
8
9
10
11
12
13
@PostMapping("/lucky")
public ResponseEntity<Map<String, String>> checkLuckyBag(
@RequestParam String luckyBag,
HttpServletRequest request,
HttpServletResponse response) {
List<String> luckyBagList = CONF.getLuckyBagList();
Profile authUser = utils.getAuthUser(request);
if (authUser == null) return new ResponseEntity<>(null, HttpStatus.FORBIDDEN);
if (luckyBagList.contains(luckyBag) && !authUser.getLuckyBagList().contains(luckyBag)) {
// count 1개 늘려서 리턴
}
}
하지만 이렇게 하면 사실 사용자가 개발자 도구 켜서 lucky-bag-1 이라는 title 을 보자마자 이거 분명 연속하는 숫자라는걸 알테고 cheating user 가 발생 할 수 밖에 없을 것이다! 열심히 준비한 이벤트가… 한순간에 물거품이 되버릴수도 있었다
어떻게 하면 사용자들이 꼼수를 안쓸까 ?
사람들이 절대로 알 수 없도록 Hash 화 하는 방법을 택했다. title 에 lucky-bag-1 이라고 명시하지 않고 SHA-256 으로 암호화 하여 8efb5ac2c2e4d72d0e540ef1721dbe4b3693ffd9f868063625349cc09f15c1a8
이값을 title에 넣고 spring 에서도 lucky-bag-1 ~ 30 을 SHA 256 으로 암호화한 값들 안에 있으면 count 를 1 올려 주도록 바꿨다. 사실 사용자가 hash 값을 보고 물론! 어쩌다 찍어 맞출수는 있겠지만 그렇게 찍어 맞췄으면 그 들인 시간이 상당했을 것이므로 그냥 이벤트 상품을 주기로 했다!
1
<img src="복주머니" class="lucky-bag" title="8efb5ac2c2e4d72d0e540ef1721dbe4b3693ffd9f868063625349cc09f15c1a8"/>
그 결과! 참여자는 300명이 훨씬 넘었지만 30개의 복주머니를 모두 찾은 사람은 단 2명으로 cheating 사용자가 없었다! 열심히 준비한 이벤트가 성공적이고 깔끔하게 끝나서 너무 다행스럽다…!