The Day I Became a Bug Hunter
This is a submission for DEV's Summer Bug Smash: Smash Stories powered by Sentry. Did anyone ask for...
개요 #
소프트웨어 테스팅 경험이 전혀 없는 개발자가 6시간짜리 버그 찾기 대회에 참가해 1위를 차지했다. 목표는 소박했다. "쓸 만한 버그 하나만 찾자."
Konark Sharma가 Dev.to의 Summer Bug Smash 기획에 기고한 글이다. 남이 만든 제품에서 처음으로 진지하게 버그를 찾아본 경험, 그날 건진 프론트엔드 버그 7가지, 결과 발표 다음 날 아침에 받은 메일까지 풀어놓은 글이다.
6시간, 그리고 준비되지 않은 참가자 #
대회 규칙은 단순했다. 한 회사의 웹사이트를 테스트해 쓸모 있는 버그를 최대한 많이 찾아 제출하는 것. 버그를 찾는 데서 끝나지 않았다. 문서로 정리하고, 재현 절차를 설명하고, 엑셀 시트에 기록해 시간 안에 제출해야 했다. 당연히 우선순위가 높은 버그일수록 점수가 높았다.
그의 자격 요건은 이 한 줄이 전부였다.
"웹사이트를 만들 줄 아니까, 부수는 것도 어렵지 않겠지."
Sharma는 전문 테스터가 아니었다. 네트워크 탭을 열자마자 치명적 취약점을 짚어내는 부류도 아니었다. 자신 없었지만 일단 뛰어들고 나중에 방법을 찾는 성격이라 신청부터 했다고 한다.
Photo by Alva Shoot on Pexels
대회 전날 밤, 그는 소프트웨어 테스팅 튜토리얼을 찾아봤다. 버그 유형, 흔한 웹 취약점, UI/UX 문제, 폼 검증, 기능 오류, 반응형 이슈까지 다음 날 살아남는 데 도움이 될 만한 건 다 훑었다.
머릿속을 떠나지 않은 질문은 하나였다. "내가 버그라고 신고한 게 버그가 아니면 어쩌지?" 자신만만하게 20건을 제출했는데 "그건 원래 그렇게 동작하는 기능입니다"라는 답이 돌아오는 장면이 상상됐다.
그래서 테스트해볼 항목을 체크리스트로 만들고 목표를 낮췄다. 하나. 진짜 버그 하나만 찾으면 그날의 도전은 성공이라고.
첫 버그는 푸터에 있었다 #
대회가 시작되자 6시간은 6시간처럼 느껴지지 않았다. 초반 한 시간은 여유로웠다. 페이지를 돌아다니고, 화면 크기를 바꿔보고, 폼에 일부러 틀린 값을 넣고, 눌리기 싫어할 법한 버튼을 계속 눌러댔다. 그가 택한 방식은 "클릭할 수 있는 건 다 클릭해서 뭐가 깨지는지 보는 극도로 성가신 사용자"였다.
몇 시간이 지나자 초조해졌다. 인상적인 발견은 아직 없었다. 그러다 푸터에 도착했다.
푸터에 링크가 여러 개 있었는데, 마우스를 올려도 클릭 가능하다는 시각적 신호가 전혀 없었다. 색이 바뀌지도, 밑줄이 생기지도 않았다.
사이트를 무너뜨릴 치명적 취약점이었냐면, 전혀 아니다. 그래도 그는 신이 났다. 첫 사용성 이슈를 찾아낸 것이다. 경력 있는 QA에게는 평범한 화요일 아침 같은 발견이었겠지만, 그에게는 푸터에 숨어 있던 제로데이를 캐낸 기분이었다.
그 순간 생각이 바뀌었다. "나는 테스트할 줄 모른다"에서 "좋아, 또 뭘 부술 수 있지?"로.
그가 제출한 버그 7가지 #
첫 발견 이후 그는 사이트를 다르게 보기 시작했다. 그냥 쓰는 대신 계속 의심했다. 이 필드를 비우면 어떻게 되지? 여기서 뒤로 가기를 누르면? 내 이름이 터무니없이 길면? 이 링크는 새 탭에서 열려야 하나? 이미 도착한 페이지로 데려가는 버튼은 왜 있지?
1. 미완성 폼 제출이 뒤로 가기를 망가뜨렸다 #
폼이 부분 제출을 어떻게 처리하는지 보려고 입력값을 하나씩 채우고 제출하고 확인하기를 반복했다. 지루한 작업이었지만 성과가 있었다. 정보를 일부만 입력한 상태에서 뒤로 가기 버튼이 제대로 동작하지 않았다. 사용자가 흐름을 취소하거나 이전 화면으로 돌아갈 수 없었고, 새로고침하거나 다른 탈출구를 찾지 않는 한 갇히는 구조였다. 폼 검증 테스트로 시작한 일이 내비게이션·상태 관리 문제를 드러낸 셈이다.
2. 검증은 작동했지만 사용자에게 말해주지 않았다 #
필수 항목을 빼고 폼을 제출하면 붉은 테두리든 에러 메시지든 포커스 이동이든, "이거 빠뜨렸어요"라는 신호가 있어야 한다. 필수 항목인 조직명을 일부러 비우고 제출했다. 제출은 정상적으로 차단됐지만 해당 필드는 강조되지 않았고 뭘 놓쳤는지 알려주는 표시도 없었다. 기술적으로 검증은 제 역할을 했지만, 사용자 눈에는 제출 버튼이 그냥 먹통인 것처럼 보였다. 그의 권고는 인라인 검증 메시지를 노출하고 문제가 된 필드를 명확히 짚어주라는 것이었다.
3. 이름은 얼마나 길어질 수 있나 #
대부분의 폼은 maxlength나 검증 규칙, 혹은 UI 처리로 텍스트 입력에 제한을 둔다. 긴 이름을 입력하기 시작했고 어딘가에서 막힐 거라 예상했다. 막히지 않았다. 계속 입력했다. 애플리케이션은 그 값을 받아들이고 저장한 뒤 UI에 그대로 다시 뿌렸다. 문제는 거기서 터졌다. 비정상적으로 긴 값이 레이아웃을 밀어내 인터페이스 일부가 깨져 보였다. 핵심은 "이름이 너무 길다"가 아니라 시스템이 길이 제한 없는 사용자 입력을 받아들이면서 UI는 그걸 표시할 준비가 안 돼 있었다는 점이다. 합리적인 입력 제한에 텍스트 줄바꿈이나 말줄임 처리를 더하면 막을 수 있는 문제였다.
4. 나란히 있는 두 링크, 전혀 다른 동작 #
내비게이션을 테스트하다가 Submissions를 누르면 현재 페이지 안의 해당 섹션으로 이동하는데, Resources를 누르면 새 탭이 열린다는 걸 발견했다. 각각만 놓고 보면 틀린 동작은 아니다. 하지만 나란히 배치된 두 요소가 서로 다르게 움직이면 인터페이스를 예측하기 어려워진다. 둘 다 같은 애플리케이션의 내부 섹션이라면 특별한 이유가 없는 한 같은 패턴을 따라야 한다는 게 그의 지적이었다. "고장"이라기보다 UI 전반의 일관성 문제다.
5. URL은 틀렸는데, 에러 메시지도 딱히 도움이 안 됐다 #
잘못된 URL과 빈 URL을 일부러 넣어 검증 방식을 확인했다. 폼은 뭔가 잘못됐다는 건 알아챘지만 무엇을 고쳐야 하는지는 설명하지 못했다. 두루뭉술한 실패 메시지는 사용자에게 URL 형식이 문제인지, 필수 항목이 빠진 건지, 아니면 다른 이유인지 추측하게 만든다. "https:// 를 포함한 올바른 URL을 입력하세요" 정도로 구체적이었다면 사용자가 바로 조치할 수 있었을 것이다.
6. 이미 있는 자리로 데려가는 버튼 #
내비게이션 버튼처럼 생기고 그렇게 동작하는 요소들이 있어서 눌러봤다. 도착지는 지금 보고 있던 그 페이지였다. 뭔가 일어날 것처럼 보이지만 클릭해도 상태나 위치가 달라지지 않았다. UX 관점에서 이건 잘못된 어포던스다. 의미 있는 동작을 하지 않는 요소라면 상호작용 가능한 것처럼 보여선 안 된다. 목적지를 제대로 주거나, 아니면 그냥 일반 텍스트로 표시하는 편이 낫다.
7. 결국 모든 링크를 의심하기 시작했다 #
내비게이션 동작이 제각각이라는 걸 알고 나서는 링크를 더 꼼꼼히 확인했다. 내부 링크, 외부 링크, 같은 탭 이동, 새 탭 이동을 하나씩 짚었다. 외부 리소스가 같은 탭에서 현재 애플리케이션을 덮어쓰는 경우를 찾아냈는데, 이러면 사용자가 작업 중이던 위치나 작성 중이던 내용을 잃게 된다. 제품의 내비게이션 정책에 따라 다르겠지만 명백한 외부 링크를 새 탭에서 열면 현재 상태를 지키고 돌아오기도 쉬워진다. 더 중요한 건 내부·외부 이동에 대한 일관된 규칙이 필요하다는 점이었다.
이 중 어느 것도 보안 커뮤니티의 화제가 될 만한 발견은 아니었다. 하지만 그는 여기서 버그에 대해 중요한 걸 배웠다고 말한다. 버그가 의미를 가지려면 애플리케이션을 통째로 죽여야 하는 게 아니다. 앞뒤가 안 맞는 작은 상호작용 하나로도 사용자는 충분히 짜증이 난다. 사용자는 문제의 원인이 JavaScript인지 CSS인지 API인지 관심이 없다. 웹사이트가 기대한 대로 움직이지 않는다는 사실만 안다.
결과 발표, 그리고 다음 날 아침의 메일 #
시간이 얼마 남지 않자 그는 발견한 내용을 정리했다. 각 이슈마다 무슨 일이 일어났는지, 무엇을 기대했는지, 어디서 발생했는지를 적었다. 반응형 문제까지 잡으려고 노트북과 휴대폰 양쪽에서 테스트했다. 마감 몇 분 전에 파일을 제출했다. 그의 첫 정식 버그 리포트였다.
완주했다는 사실은 뿌듯했지만 찜찜함이 남았다. 발견한 것 대부분이 UI, UX, 내비게이션, 검증 같은 프론트엔드 문제였기 때문이다. 대형 네트워크 취약점도, 인증 우회도, 화면에 녹색 글자가 쏟아지는 해커 영화 같은 순간도 없었다. 그냥 프론트엔드 버그였다. 그래서 그는 자신이 잘하지 못했다고 짐작했다.
이 버그 헌팅 이벤트는 더 큰 대회에 딸린 미니 챌린지였다. 그가 신경 쓴 쪽은 본 대회였다. 결과가 나왔고, 3위 안에 들지 못했다. 실망감이 미니 챌린지의 존재를 완전히 덮어버렸다.
그리고 다음 날 아침, 주최 측의 메일이 와 있었다. 뭔가에 당선됐다는 내용이었다. 3등이겠거니, 아니면 참가 위로상이겠거니 생각하며 메일을 열었다.
1위였다.
전문 테스팅 경험 없이 참가한 대회, 전날 밤 세운 전략이라곤 "제발 진짜 버그 하나만 찾게 해주세요"가 전부였던 대회에서였다. 그가 찾아낸 버그들은 실제로 쓸모가 있었고, 일부는 이후 해당 웹사이트의 UI/UX 개선에 반영됐다.
가장 큰 버그는 웹사이트에 없었다 #
돌아보면 그날 발견한 가장 큰 것은 웹사이트 안에 숨어 있지 않았다. 자기 자신에 대해 세워둔 가정이었다.
그는 "나는 개발자지 테스터가 아니니까 잘하지 못할 것"이라 생각하며 참가했다. 그런데 개발자라는 점이 오히려 눈에 띄게 도와줬다. 웹사이트가 어떻게 동작해야 하는지 알고 있었고, 사용자가 버튼을 누르고 폼을 제출하고 화면 크기를 바꾸고 페이지를 오갈 때 무엇을 기대하는지 알고 있었다.
6시간 만에 테스터가 된 건 아니다. 이미 알고 있던 것을 다른 각도에서 썼을 뿐이다.
그는 버그 하나만 찾자는 마음으로 들어갔다가 1위로 나왔다. 뭔가를 해보기 전에 꼭 전문가여야 하는 건 아니다. 누르면 안 될 것 같은 버튼을 눌러보고 "이러면 어떻게 되지?" 하고 물어볼 호기심이면 충분할 때도 있다.
이 글은 위 출처를 바탕으로 한국 독자를 위해 재작성한 기사입니다. 원문의 사실과 수치에 근거하며, 별도의 견해를 포함하지 않습니다.

