- 05 Dec, 2025
모의해킹 중 실수로 서비스를 터뜨린 날 - 그 후 어떻게 했나?
모의해킹 중 실수로 서비스를 터뜨린 날 - 그 후 어떻게 했나? 화요일 오후 3시 42분 모의해킹 중이었다. 결제 API 침투 테스트. OWASP Top 10 체크리스트 따라가는 중. SQL Injection 테스트 페이로드 날렸다. ' OR '1'='1 같은 거. 기본 중의 기본. 근데 응답이 이상했다. 500 에러. 한 번 더. 또 500.슬랙에 알림 떴다. "결제 시스템 장애 발생" "고객 결제 불가" "긴급 점검 중" 심장이 멈췄다. 15초 후 손이 떨렸다. 진짜로. 내가 터뜨린 거다. 확신했다. 타임스탬프 확인했다. 내 테스트: 15:42:38 장애 시작: 15:42:39 1초 차이. 로그 봤다. 내 IP 주소. 내 테스트 페이로드. 데이터베이스 커넥션 풀이 다 죽어있었다. "씨발." 입 밖으로 나왔다. 즉시 보고 팀장한테 슬랙 날렸다. "제가 터뜨린 것 같습니다" "지금 즉시 복구 지원하겠습니다" 전화 왔다. 떨리는 목소리로 받았다. "뭐 했어?" "SQL Injection 테스트요. 근데..." "스테이징이야 프로덕션이야?" "..." 침묵. VPN 설정 확인했다. 프로덕션 DB 접속되어 있었다. "프로덕션입니다." 팀장 한숨 소리. 길게.상황 파악 10분 CTO 포함 긴급 회의. 개발팀장, 인프라팀장, 보안팀장, 나. 내가 설명했다. "SQL Injection 페이로드 날렸고요" "데이터베이스 커넥션이 과부하 걸렸습니다" "제가 스테이징인 줄 알고..." 변명 아니다. 사실 그대로. CTO가 물었다. "데이터 유실은?" "없습니다. 확인했습니다." "개인정보 유출은?" "없습니다. Read 쿼리만 실행됐습니다." 로그 파일 공유했다. 다 떨렸다. 인프라팀장이 DB 재시작 중. 커넥션 풀 리셋. 5분 뒤 복구 완료. 15:57. 15분간 장애. 피해 규모 고객 278명 결제 실패. 예상 매출 손실 약 1200만원. CS 문의 83건. 장애 공지 올라갔다. "일시적 시스템 점검" "불편을 드려 죄송합니다" 고객들은 몰랐다. 보안 테스터가 터뜨렸다는 걸. 근데 회사는 안다. 내가 터뜨렸다는 걸. 즉시 수습 작업 오후 4시부터 밤 11시까지. 내가 한 일:전체 로그 분석 리포트 작성 영향받은 트랜잭션 리스트 추출 재시도 필요 건 식별 (개발팀 전달) 근본 원인 분석 문서화 재발방지 대책 수립왜 터졌나. DB 커넥션 풀 설정이 약했다. 맞다. 근데 그건 핑계다. 진짜 문제는 내가 프로덕션에 접속했다는 것. 스테이징인 줄 착각했다. VPN 설정 확인 안 했다. 기본 중의 기본을 안 지켰다.보고서 작성 11시 반. 최종 보고서 완성. 사고 경위15:42 보안 테스터가 프로덕션 환경에서 침투 테스트 실시 SQL Injection 페이로드로 DB 커넥션 풀 소진 15분간 결제 서비스 장애직접 원인프로덕션/스테이징 환경 미확인 테스트 전 체크리스트 미준수근본 원인VPN 프로파일 네이밍이 불명확 프로덕션 접근 권한 통제 미흡 모의해킹 가이드라인 부재재발방지 대책프로덕션 DB 접근 시 2단계 승인 필요 VPN 프로파일명 명확화 (PROD-빨간색 표시) 침투 테스트 체크리스트 의무화 프로덕션 테스트 시 Read-Only 계정만 사용 부하 테스트 전 Rate Limiting 확인솔직하게 썼다. 내 실수 숨기지 않았다. 수요일 오전 회의 임원 회의실. 긴장됐다. CTO가 먼저 말했다. "보고서 봤어요. 솔직하네요." "네." "처벌은 당연히 있습니다." 각오했다. "이번 달 성과급 50% 삭감" "그리고..." 잘렸나 싶었다. "재발방지 대책 실행 책임자 맡으세요" "네?" "당신이 제일 잘 알잖아요. 어떻게 터지는지." 의외였다. 팀장이 말했다. "실수는 누구나 해. 근데 수습을 어떻게 하느냐가 중요해." "15분 만에 보고했고" "7시간 동안 수습했고" "솔직한 보고서 썼어" "이게 프로야" 눈물 날 뻔했다. 참았다. 그 후 2주 재발방지 대책 실행했다.프로덕션 DB 접근 권한 재설계보안팀도 기본은 Read-Only Write 권한은 Jira 티켓 + 팀장 승인VPN 프로파일 UI 개선PROD는 빨간색, 경고 팝업 STAGING은 노란색 DEV는 초록색침투 테스트 체크리스트 제작 [ ] 환경 확인 (STAGING임을 3번 체크) [ ] Read-Only 계정 사용 [ ] 테스트 범위 문서화 [ ] 부하 영향도 사전 검토 [ ] 팀장 승인모의해킹 가이드라인 문서화전사 공유 신규 입사자 필독주간 보안팀 회의에서 Near-Miss 공유"나 이번 주에 이런 실수 뻔했어" 서로 배우는 문화한 달 후 성과급 50% 깎였다. 150만원. 아팠다. 근데 마땅했다. 대신 얻은 것. 개발팀이 보안팀 보는 눈이 달라졌다. "보안팀도 실수하네. 우리만 그런 게 아니구나" "근데 수습 진짜 빠르더라" 예전엔 보안 이슈 리포트하면 "나중에요~" 했는데 이제는 "언제까지 고칠게요" 한다. 왜? 내가 터뜨렸을 때를 봤으니까. 수습하는 모습도 봤으니까. 신뢰가 생겼다. 3개월 후 회고 분기 회고 때 발표했다. "제가 3개월 전에 프로덕션 터뜨렸습니다" 웃음 나왔다. 다들 알던 사실. "그 후 바뀐 것들"프로덕션 장애 0건 (보안 테스트 관련) 침투 테스트 체크리스트 준수율 100% 타팀에서도 우리 가이드라인 참고 Near-Miss 공유 문화 정착"배운 것"실수는 시스템으로 막아야 한다 솔직한 보고가 신뢰를 만든다 수습 속도가 전문성이다CTO가 말했다. "이게 성숙한 조직이에요" "실수를 숨기는 게 아니라" "실수에서 배우는 거" 박수 나왔다. 부끄러웠다. 지금 여전히 모의해킹한다. 침투 테스트한다. 근데 체크리스트는 무조건 본다. 환경 확인. 세 번. STAGING 맞나. 또 확인. VPN 프로파일 색상. 노란색 맞나. 강박이 생겼다. 좋은 의미로. 후배가 입사했다. 보안 QA 신입. 첫날 내가 말했다. "내가 3개월 전에 프로덕션 터뜨렸어" "어떻게요?" "체크리스트 안 봐서" 그리고 가이드라인 줬다. "이거 만든 사람이 나야" "왜냐면 터뜨려봐서 알거든" 후배가 웃었다. "선배, 솔직하시네요" "보안 일 하려면 솔직해야 해" "취약점 찾는 것도" "내 실수 인정하는 것도" 교훈이랄 것도 없지만 실수는 한다. 보안 전문가도 사람이니까. 중요한 건 그 다음이다. 15초 만에 인정할 건가. 15분 만에 보고할 건가. 15시간 동안 수습할 건가. 아니면 숨길 건가. 나는 15초 만에 알았다. "내가 터뜨렸다" 그게 시작이었다.프로덕션 터뜨린 날. 최악의 날이었다. 근데 최고의 배움이었다. 체크리스트는 생명이다.
- 04 Dec, 2025
Burp Suite 라이센스 비용이 아까워서 커뮤니티 버전으로 버티는 팁
라이센스 비용이 아깝다 Burp Suite Pro는 연 $449. 한화로 약 60만원. 회사에서 쓰는 건 회사 돈이니 상관없다. 그런데 주말에 개인 버그바운티 할 때는 내 돈이다. 60만원이면 원룸 월세 절반이다. 그래서 커뮤니티 버전으로 버틴다. 벌써 2년째다. Pro 쓰는 사람들은 "돈 벌려면 투자해야지"라고 한다. 맞는 말이다. 근데 아직은 아깝다. 커뮤니티 버전도 잘 쓰면 충분하다. 불편하긴 하다. 그래도 못할 건 없다. 오늘은 그 노하우를 정리한다.Pro와 Community의 차이 Pro 버전 주요 기능:자동 스캐너 (Active Scan) Intruder의 속도 제한 해제 Extension 추가 기능들 저장/로드 기능 강화 협업 기능Community 버전 제약:Active Scan 없음 (수동으로 해야 함) Intruder 속도 느림 (쓰레드 제한) 일부 Extension 제한 프로젝트 저장 안 됨솔직히 Active Scan 없는 게 제일 아프다. Pro는 버튼 하나면 취약점 찾아준다. Community는 내가 직접 찾아야 한다. 근데 생각해보면 수동 테스트가 실력이다. 자동 스캐너만 믿으면 놓치는 것도 많다. 그렇게 스스로 위로한다.Intruder 속도 제한 우회 Community 버전 Intruder는 느리다. 진짜 느리다. 한 번에 하나씩 요청 보낸다. 1000개 페이로드면 1000번 기다린다. Pro는 쓰레드 여러 개로 빠르게 보낸다. 해결책:Python으로 직접 만든다 ffuf 같은 외부 툴 쓴다 Turbo Intruder Extension 쓴다나는 Python을 주로 쓴다. import requests for payload in payloads: response = requests.post(url, data=payload)이런 식으로 간단하게 만든다. 멀티쓰레딩 추가하면 Pro보다 빠르다. ffuf도 좋다. 디렉토리 부르트포싱할 때 쓴다. ffuf -u https://target.com/FUZZ -w wordlist.txt속도는 ffuf가 제일 빠르다. Turbo Intruder는 Burp 안에서 쓸 수 있다. Python 스크립트 기반이다. 속도 제한 없다. 세 가지 다 익혀두면 Intruder 없어도 산다. Repeater가 진짜 핵심 Community 버전에서 가장 많이 쓰는 건 Repeater다. 요청 수정해서 다시 보내고, 응답 확인하고, 또 수정하고. SQL Injection 찾을 때:' OR '1'='1 넣어보고 admin' -- 시도하고 UNION SELECT 테스트하고XSS 찾을 때:<script>alert(1)</script> <img src=x onerror=alert(1)> javascript:alert(1)수동이지만 정확하다. 오탐이 없다. 자동 스캐너는 False Positive 많다. 일일이 확인해야 한다. Repeater는 내가 보낸 요청, 내가 본 응답이다. 확실하다.Extension 활용 Community에서도 쓸 수 있는 Extension이 많다. 내가 자주 쓰는 것:Logger++: 모든 요청 로깅 Autorize: 권한 테스트 자동화 Param Miner: 숨겨진 파라미터 찾기 Turbo Intruder: 속도 제한 우회 JS Link Finder: JS 파일에서 엔드포인트 추출Logger++는 필수다. Community는 프로젝트 저장이 안 되니까 로그라도 남겨야 한다. Autorize는 권한 테스트할 때 편하다. 일반 유저로 로그인해서 어드민 API 호출하는 걸 자동으로 해준다. JS Link Finder는 숨겨진 엔드포인트 찾을 때 좋다. React, Vue 같은 SPA는 API 주소가 JS에 다 있다. Extension만 잘 써도 Pro 부럽지 않다. 수동 테스트 체크리스트 자동 스캐너 없으니 체크리스트가 중요하다. 내 체크리스트: 인증/인가:토큰 없이 API 호출 가능한지 다른 유저 ID로 권한 탈취 가능한지 JWT 토큰 검증 제대로 하는지입력값 검증:SQL Injection (싱글쿼트 테스트) XSS (스크립트 태그 삽입) IDOR (숫자 ID 바꿔보기) Path Traversal (../../etc/passwd)비즈니스 로직:가격 조작 가능한지 수량 음수로 바꿔지는지 쿠폰 중복 사용 가능한지정보 노출:에러 메시지에 스택 트레이스 있는지 API 응답에 민감정보 있는지 주석에 비밀번호 있는지하나씩 체크하면서 Repeater로 테스트한다. 시간 걸린다. 근데 확실하다. 다른 툴과 병행 Burp만 쓰면 한계가 있다. 같이 쓰는 툴들: Nmap: 포트 스캔, 서비스 버전 확인 ffuf: 디렉토리/파일 브루트포싱 sqlmap: SQL Injection 자동화 nuclei: 알려진 취약점 스캔 httpx: 대량 URL 상태 확인 이것들 다 무료다. nuclei는 특히 좋다. YAML 템플릿으로 취약점 스캔한다. CVE 나오면 바로 템플릿 업데이트된다. nuclei -u https://target.com -t cves/이것만 해도 최신 취약점 찾을 수 있다. Burp는 프록시+Repeater로 쓰고, 나머지는 외부 툴로 보완한다. 실제 버그바운티 사례 지난달 버그바운티에서 $500 받았다. Community 버전으로만 찾았다. 타겟: 국내 이커머스 플랫폼 발견 과정:Burp Proxy로 트래픽 캡처 주문 API 발견: POST /api/order Repeater로 요청 확인 price 파라미터를 음수로 변경 요청 보냈더니 성공 주문하면서 돈 받는 버그리포트 제출하고 2주 뒤 $500 받았. 자동 스캐너 안 써도 찾을 수 있다. 로직 버그는 수동이 더 낫다. Pro 사야 하는 경우 솔직히 Pro가 필요한 경우도 있다. 대량 타겟 테스트: 스타트업 100개 테스트해야 하면 자동 스캐너 필요하다. 협업: 팀으로 일하면 프로젝트 공유 기능이 편하다. 시간이 돈: 시간당 수익이 높으면 자동화가 이득이다. 회사 돈: 회사 프로젝트면 당연히 Pro 써야 한다. 근데 개인 버그바운티, 공부 목적이면 Community로 충분하다. 실력 늘리기엔 수동이 더 좋다. 왜 취약점이 생기는지 이해하게 된다. 돈 모으는 중 올해 목표는 버그바운티로 1000만원 벌기다. 지금까지 300만원 정도 벌었다. 7개월 남았다. 1000만원 모으면 Pro 살 거다. 그래도 600만원 남는다. 그때까지는 Community로 버틴다. 불편하지만 불가능하진 않다. 오히려 제약이 실력을 키운다고 생각한다. 없으니까 더 머리 쓴다. Python 스크립트도 늘고, 체크리스트도 정교해진다. Pro 사는 날이 목표다. 근데 그 전까지의 과정도 배움이다. 커뮤니티의 힘 Burp Community Edition 유저들 커뮤니티가 있다. Reddit, Discord, 블로그에서 팁 공유한다. "이 Extension 좋더라", "이렇게 우회하더라" 같은 정보들. 혼자 쓰는 것보다 훨씬 강력하다. Pro 유저들은 돈으로 해결한다. Community 유저들은 지식으로 해결한다. 어떻게 보면 더 멋있다.Community 버전, 제약이지만 제한은 아니다. 방법은 항상 있다.
- 03 Dec, 2025
취약점을 못 찾으면 '없는 건지, 못 찾은 건지' 자책하는 밤
취약점을 못 찾으면 '없는 건지, 못 찾은 건지' 자책하는 밤 오후 3시, 스캔 시작 신규 결제 API 테스트 들어갔다. 개발팀이 자신 있다고 했다. "이번엔 보안 완벽하게 했습니다." 그 말 들으면 더 의심스럽다. Burp Suite 켰다. Proxy 설정하고 트래픽 캡처 시작. 일단 자동 스캔 돌려놨다. 커피 한 잔 마시러 갔다. 돌아와서 결과 확인. Low 몇 개. Medium 하나. 다 거짓 양성이다. 수동 테스트 시작했다. Authorization 헤더 빼봤다. 정상 처리됐다. 이상하다. 토큰 변조해봤다. 401 에러 떴다. 정상이다. SQL Injection 시도. Single quote, double quote, comment. 다 필터링됐다.XSS 테스트 들어갔다. Script 태그, event handler, encoded payload. 전부 sanitize됐다. 깔끔하다. 너무 깔끔하다. 이게 맞나. 오후 5시 됐다. 취약점 없다. 하나도. 6시, 퇴근 시간 동료들 하나씩 퇴근한다. "오늘 뭐 찾았어?" 물어본다. "아직요." 대답했다. "괜찮아, 없으면 없는 거지." 웃으면서 말한다. 없으면 없는 거. 그게 그렇게 간단하지 않다. 보안 QA 6년 차다. 취약점 못 찾는 날이 제일 불안하다. 찾으면 보람 있다. 회사 지켰다는 기분. 못 찾으면 모르겠다. 정말 안전한 건지, 내가 못 찾은 건지. 개발자들은 취약점 없으면 좋아한다. 당연하다. 수정할 거 없으니까. 나는 불안하다. 뭔가 놓친 것 같다. 리포트에 뭐라고 쓸까. "취약점이 발견되지 않았습니다." 이 한 줄. 허전하다. 믿을 수 있을까. 나도 확신 없는데. 여자친구한테 문자 왔다. "저녁 먹자." 답장 보냈다. "조금만 더." 남았다. 혼자. 8시, 다시 시작 처음부터 다시 봤다. 놓친 엔드포인트 있을 수 있다. API 문서 다시 읽었다. 15개 엔드포인트. 다 테스트했다. Rate limiting 확인했다. 잘 걸려 있다. 1분에 100 요청. Brute force 막힌다. IDOR 테스트했다. user_id 변조. 403 에러. 정상이다.SSRF 시도했다. 내부 IP 호출. 막혔다. XXE 테스트. XML 파싱 안 쓴다. GraphQL injection. GraphQL 안 쓴다. NoSQL injection. MongoDB 쿼리 검증 됐다. 2시간 더 지났다. 여전히 없다. 동료한테 물어볼까 생각했다. "내가 놓친 거 있을까요?" 부끄럽다. 6년 차가 이런 질문. 10시, 자책 시작 컴퓨터 앞에 앉아 있다. 화면만 본다. 뭘 더 해야 할까. OWASP Top 10 다시 확인했다. Injection. 확인했다. Broken Authentication. 확인했다. Sensitive Data Exposure. 암호화 됐다. XML External Entities. 안 쓴다. Broken Access Control. 확인했다. Security Misconfiguration. 기본 설정 변경됐다. XSS. 확인했다. Insecure Deserialization. 안 쓴다. Using Components with Known Vulnerabilities. 버전 다 최신이다. Insufficient Logging. 로깅 잘 된다. 다 확인했다. 그래도 불안하다. 작년 생각났다. 3일 동안 못 찾았던 API. "안전합니다" 리포트 올렸다. 2주 후에 버그바운티 해커가 찾았다. JWT 알고리즘 혼동 취약점. 'none' 알고리즘 허용했었다. 나는 못 봤다. 팀장 불렀다. "이거 왜 못 찾았어?" 할 말 없었다. "죄송합니다." 그것뿐이었다. 기본적인 건데. 6년 차가 놓쳤다. 그 이후로 더 신경 쓴다. 그래도 여전히 놓칠까 봐 무섭다. 11시, 마지막 시도 JWT 다시 봤다. 알고리즘 확인. RS256. 고정됐다. 'none' 안 된다. 서명 검증 잘 된다. Expiration 확인. 1시간. 적절하다. Refresh token 로직. 정상이다. Race condition 테스트했다. 동시에 100개 요청. 처리 잘 된다. 중복 안 생긴다. Business logic 봤다. 포인트 적립 로직. 음수 입력. 거부됐다. 환불 로직. 금액 확인 잘 된다. 쿠폰 중복 사용. 막혔다.File upload 기능 없다. CSRF 토큰 잘 된다. Clickjacking X-Frame-Options 설정됐다. CORS 정책 엄격하다. 자정 됐다. 9시간 봤다. 없다. 진짜 없는 건가. 아니면 내가 못 보는 건가. 자정, 집으로 퇴근했다. 사무실 나왔다. 차가운 바람. 12월이다. 택시 탔다. 창밖 본다. 불 켜진 건물들. 저기도 누군가 일한다. 보안 QA만 이럴까. 아니겠지. 여자친구한테 전화 왔다. "아직도 일해?" 목소리 졸리다. "퇴근했어. 미안." 걱정한다. "너무 늦게까지 하지 마." 설명 못 한다. 이 불안감. 취약점 찾으면 일 잘했다는 거다. 못 찾으면 모른다. 일을 잘한 건지, 못한 건지. 개발자는 다르다. 기능 만들면 된다. 동작하면 성공이다. 보안 QA는 애매하다. 안전하다는 걸 어떻게 증명하나. '취약점이 없다'는 증명은 없다. '찾지 못했다'는 것뿐이다. 새벽 1시, 침대에서 누웠다. 잠 안 온다. 핸드폰 켰다. 보안 뉴스 본다. 새로운 CVE 나왔다. npm 패키지 취약점. 우리 프로젝트에 있나 확인해야겠다. 생각이 꼬리를 문다. 오늘 테스트한 API. 진짜 안전할까. JWT 서명 검증 로직 직접 봤나. 소스 코드 확인 안 했다. 블랙박스로만 봤다. 내일 개발팀한테 물어봐야겠다. "JWT 라이브러리 뭐 쓰세요?" 혹시 오래된 버전. 알려진 취약점 있을 수 있다. 근데 그것도 찾으면 찾는 거고. 못 찾으면 모른다. 버그바운티 해커들 생각난다. 걔네는 어떻게 찾을까. 나보다 잘 찾는다. 돈도 번다. 나는 월급 받으면서 못 찾는다. 작년 그 해커. LinkedIn 찾아봤다. 19살이었다. 나보다 어리다. 실력은 훨씬 좋다. 질투 나는 건 아니다. 그냥 자괴감. 이 일 6년 했는데. 19살한테 진다. 새벽 2시, 검색 일어나서 노트북 켰다. JWT 취약점 검색했다. Algorithm confusion, Key confusion, KID injection, JKU/X5U claim abuse. 다 아는 거다. 다 테스트했다. 그래도 뭔가 놓친 것 같다. Stack Overflow 봤다. "How to test JWT properly." 답변 읽었다. 내가 하는 거랑 똑같다. YouTube 켰다. "Advanced JWT attacks." 40분짜리 영상. 봤다. 새로운 거 없다. 다 아는 내용이다. 그래도 불안하다. 문제는 이거다. 내가 아는 방법으로만 테스트한다. 모르는 취약점은 못 찾는다. 당연한 거다. 근데 받아들이기 힘들다. 보안팀장이 말했다. "완벽한 보안은 없어. 최선을 다하면 돼." 위로가 안 된다. 최선이 뭔데. 어디까지가 최선인가. 9시간 테스트했다. 최선이다. 근데 충분한가. 새벽 3시, 포기 노트북 껐다. 누웠다. 천장 본다. 어둡다. 내일 리포트 써야 한다. "신규 결제 API 보안 테스트 결과, 주요 취약점이 발견되지 않았습니다. 인증, 인가, 입력 검증, 에러 처리 등 전반적인 보안 구현이 양호합니다." 이렇게 쓸 거다. 사실이다. 발견되지 않았다. 없다고 안 했다. 발견되지 않았다. 개발팀은 좋아할 거다. "보안 테스트 통과했습니다!" 뿌듯해할 거다. 나는 불안할 거다. 배포되고 나서도. 실 서비스 올라가고 나서도. 해커가 찾을까 봐. 뉴스 뜰까 봐. "○○ 핀테크 결제 API 해킹." 댓글 달릴까 봐. "보안팀 뭐했냐." 팀장 부를까 봐. "이거 테스트 안 했어?" 했다. 9시간 했다. 최선을 다했다. 근데 못 찾았다. 이게 제일 무섭다. 열심히 했는데 결과가 없는 것. 아니다. 결과가 있는데 믿을 수 없는 것. 새벽 4시, 마음 정리 생각을 바꿔야 한다. 이건 알고 있다. 취약점을 못 찾는 게 실패가 아니다. 찾을 수 있는 걸 놓친 게 실패다. 찾을 수 없는 건 어쩔 수 없다. 내가 할 수 있는 건 했다. OWASP Top 10 확인했다. 알려진 공격 다 시도했다. Business logic 검토했다. 소스 코드 리뷰 요청할 거다. 9시간 집중했다. 더 할 수 있는 게 있나. 있다. 항상 있다. 무한정 시간 쓸 수는 없다. 선을 그어야 한다. 여기까지가 내 책임이다. 나머지는 운이다. 아니다. 나머지는 배포 후 모니터링이다. 침입 탐지 시스템이다. 버그바운티 프로그램이다. 혼자 다 막을 수 없다. 팀으로 한다. 회사 전체가 한다. 조금 마음이 편해진다. 조금. 새벽 5시, 잠 눈 감는다. 여전히 불안하다. 근데 받아들인다. 내일 출근하면 리포트 쓸 거다. "취약점 발견되지 않음." 자신 있게 쓸 거다. 최선을 다했으니까. 그리고 다음 테스트 들어갈 거다. 또 찾을 거다. 또 못 찾을 수도 있다. 또 불안할 거다. 이게 보안 QA다. 찾으면 보람 있고, 못 찾으면 불안하다. 끝이 없다. 근데 누군가는 해야 한다. 회사 지키는 일. 사용자 지키는 일. 내일도 한다. 모레도 한다. 잠든다.9시간 테스트하고 못 찾았다. 내일 또 한다.
- 03 Dec, 2025
SQL Injection과 XSS는 자동으로 눈에 들어온다 - 보안 QA의 강박관념
SQL Injection과 XSS는 자동으로 눈에 들어온다 - 보안 QA의 강박관념 눈에 보이는 게 달라졌다 아침 출근길. 지하철에서 폰으로 뉴스 앱 켰다. 로그인 화면 보자마자 머릿속에 자동으로 떠올랐다. '이 입력 폼, 파라미터 검증 되나?' 회사 도착. 엘리베이터 광고 화면에 QR코드. 스캔하라고 한다. '이거 redirect 검증했을까?' 병이다. 진짜 병. 보안 QA 4년차. 이제 직업병 수준이다. 웹사이트 하나 보면 자동으로 분석 모드 들어간다. F12 개발자 도구는 습관적으로 연다.어제 점심시간. 팀 회식 장소 검색했다. 맛집 예약 사이트 들어갔다. URL 파라미터에 id=123 보였다. 손이 자동으로 움직였다. id=123' OR 1=1-- 입력. 에러 페이지 떴다. MySQL syntax error. '역시. SQL Injection 취약점 있네.' 밥 먹으러 가는데 취약점부터 찾았다. 여자친구가 한숨 쉬었다. "또 시작이야?" 커피숍 WiFi는 전쟁터 주말 오후. 동네 카페 갔다. 노트북 켜고 작업하려는데. 공용 WiFi 보였다. 비밀번호 없음. 머릿속이 복잡해진다. '누가 패킷 스니핑하면? MITM 공격하면?' HTTPS 확인. 인증서 검증. VPN 켰다. 그제야 안심. 옆 테이블 대학생. 맥북으로 인터넷뱅킹 중. HTTP 사이트였다. 평문 통신. 말해주고 싶었다. 참았다. '내가 이상한 사람 되겠지.'집에서도 마찬가지다. 공유기 설정 2주마다 확인한다. 펌웨어 업데이트 알림 오면 바로 적용. 기본 비밀번호? 그런 거 없다. 여자친구가 놀러 왔다. "왜 WiFi 비밀번호가 32자야?" "WPA3 쓰고 있어. 안전해." "...그래." IoT 기기도 못 믿는다. 집에 있는 스마트 전구. 기본 설정으로 쓰는 사람 많다. 나는 펌웨어 뜯어봤다. 취약점 2개 발견. 제조사에 리포트 보냈다. 답은 없었다. 새 서비스는 샌드박스 회사에 신규 서비스 론칭 일주일 전. 개발팀에서 "테스트 좀 해주세요" 메시지. 내가 기다리던 순간이다. Burp Suite 켰다. 프록시 설정. 모든 요청 intercept 모드. 하나하나 뜯어본다. 첫 번째 발견. 회원가입 API. 이메일 검증 없음. HTML 태그 그대로 저장. Stored XSS 가능. 심각도 High. 두 번째. 비밀번호 찾기 기능. 토큰이 sequential 하다. 1, 2, 3, 4... 다른 사람 계정 접근 가능. Critical.세 번째. 관리자 페이지. /admin URL 직접 접근 시도. 인증 우회됐다. 권한 검증 없음. "이거 그냥 오픈하는 거예요?" 리포트 작성했다. A4 12장. 취약점 23개. Critical 5개, High 11개. 개발팀 팀장 얼굴이 하얗게 질렸다. "론칭 연기해야 할 것 같은데요." "예산이... 일정이..." "해킹당하면 더 비쌉니다." 결국 2주 연기. 다 고쳤다. 론칭 후 별 일 없었다. 아무 일 없는 게 내 일 잘한 거다. OWASP Top 10은 성경 보안 QA 처음 시작할 때. 선배가 말했다. "이거부터 외워." OWASP Top 10. 웹 보안 취약점 톱10. 지금은 자다가도 말할 수 있다.Broken Access Control Cryptographic Failures Injection Insecure Design Security Misconfiguration ...현장에서 가장 많이 보는 건. SQL Injection, XSS, CSRF. 클래식하지만 아직도 많다. 작년에 테스트한 서비스 30개. 26개에서 Injection 취약점 발견. 20개에서 XSS 가능. 15개에서 권한 검증 누락. 개발자들에게 물어봤다. "왜 안 막으세요?" "바쁘니까요. 나중에 하려고요." 나중은 없다. 해커는 지금 공격한다. 입력 폼 보면 자동 반응 식당 예약 사이트. 리뷰 작성란 봤다. 손가락이 자동으로 움직였다. <script>alert('XSS')</script> 엔터 쳤다. 새로고침. 팝업 떴다. 'XSS' 메시지. "역시나." 검색창도 마찬가지다. ' OR '1'='1 admin'-- <img src=x onerror=alert(1)> 습관적으로 입력한다. 정상 작동하면 실망한다. 에러 나면 희열 느낀다. 여자친구 쇼핑몰 앱 쓸 때. "이거 괜찮아?" "잠깐만." 폼 테스트 시작. "...그냥 사도 돼?" "아직 확인 중." 30분 뒤. "취약점 5개 발견. 다른 앱 써." "그냥 옷 사고 싶었는데..." 버그바운티는 부업 주말마다 한다. 버그바운티. HackerOne, Bugcrowd 같은 플랫폼. 기업들이 취약점 찾으면 돈 준다. 지난주 토요일. 집에서 작업. 글로벌 핀테크 기업 프로그램 참여. 4시간 테스트. IDOR 취약점 발견. 다른 사람 계좌 정보 볼 수 있었다. 리포트 제출. Critical 등급. 일주일 뒤 답장 왔다. "$3000 보상. 감사합니다." 환율 계산. 약 400만원. 주말 4시간 투자로 400만원. 시급으로 치면 100만원. 회사 월급보다 나을 때 있다. 작년 버그바운티 수입. 총 $15000. 약 2000만원. 용돈 수준 아니다. 부수입 쏠쏠하다. 하지만 매번 찾는 건 아니다. 10개 테스트하면 2~3개 발견. 운도 따라야 한다. 먼저 찾은 사람이 임자. 개발자와의 줄다리기 보안 QA의 숙명. 개발팀과 싸우는 것. "이거 취약점입니다." "근데 영향도가 낮잖아요?" "지금은 낮아도 조합하면 심각합니다." "일정이 촉박한데..." 매번 반복되는 대화. 보안은 항상 우선순위 밀린다. 기능 개발이 먼저. 보안은 '나중에'. 작년 프로젝트. XSS 취약점 리포트 5개 올렸다. 2개만 수정됐다. 3개는 '차기 버전에'. 3개월 뒤. 해당 취약점으로 공격 시도 로그 발견. 다행히 막았다. 개발팀에 다시 얘기했다. "그때 말씀드렸던 건데요." "...수정하겠습니다." 말이 통하는 개발자도 있다. 보안 의식 있는 사람. 코드 짤 때부터 고려한다. 입력 검증, 출력 인코딩, 파라미터화된 쿼리. 그런 개발자 만나면 행복하다. 일이 술술 풀린다. 취약점 적게 나온다. 서로 존중한다. 실제 해킹 사고 났을 때 2년 전 일이다. 경쟁사에서 해킹 사고 났다. 고객 정보 10만 건 유출. 뉴스 봤다. SQL Injection 공격이었다. 기본 중의 기본. '내가 테스트했으면 막았을 텐데.' 우리 회사 긴급 회의. "우리도 점검합시다." 일주일 동안 전수 조사. 밤샘 작업 3일. 발견된 취약점 47개. Critical 3개 즉시 수정. High 등급 일주일 내 패치. Medium 이하 2주 내. 그때 느꼈다. 사고 나기 전에 막는 게 내 일. 조용히 위험을 제거하는 것. 티 안 나는 영웅. 해킹당한 회사 보안팀. 다 잘렸다고 들었다. '보안팀 뭐했어?' 비난. 마음이 아팠다. 우리도 언제든 당할 수 있다. 완벽한 보안은 없다. 제로데이 공격, APT, 내부자 위협. 할 수 있는 건 최선을 다하는 것. 공격자처럼 생각하기 보안 QA의 핵심. 공격자 관점으로 생각한다. '내가 해커라면 어떻게 뚫을까?' 일반 QA와 다른 점. 그들은 정상 시나리오 테스트. 우리는 비정상 시나리오. 상상력이 무기다. 로그인 기능 테스트. 일반 QA: 올바른 ID/PW 입력. 보안 QA: SQL Injection 시도 Brute Force 공격 Session Hijacking CSRF 토큰 검증 Rate Limiting 확인파일 업로드 기능. 일반 QA: 정상 파일 업로드. 보안 QA:악성 스크립트 업로드 확장자 우회 시도 대용량 파일로 DoS 경로 조작 (Path Traversal)항상 묻는다. "이걸 악용하면 뭐가 가능할까?" "이 기능을 의도와 다르게 쓰면?" "여러 취약점을 조합하면?" 동료들이 말한다. "너는 항상 나쁜 쪽으로 생각하네." 맞다. 그게 내 일이다. 선한 의도로 나쁜 생각을 한다. 화이트 해커의 자부심 술자리에서 자기소개. "보안 QA 합니다." "해커세요?" "화이트 해커요." 블랙 해커와 다르다. 우리는 선한 편. 시스템 지키는 사람. 공격 기술은 같지만 목적이 다르다. 가끔 유혹 있다. 발견한 취약점 악용하면? 고객 정보 팔면 돈 된다. 암호화폐 거래소 뚫으면 대박. 하지만 안 한다. 윤리 문제도 있고. 무엇보다 자부심이 있다. 내가 지키는 시스템. 내가 보호하는 고객. 화이트 해커 커뮤니티. 서로 존중한다. 발견한 취약점 공유. 제로데이 정보 교환. 다 공익을 위해서. 블랙 해커 되면 돈 더 벌까? 모르겠다. 안 해봐서. 지금도 만족한다. 연봉 7000에 버그바운티 2000. 떳떳하게 번다. 끝없는 공부 보안 분야는 빠르다. 매일 새로운 취약점. 매주 새로운 공격 기법. 공부 안 하면 도태된다. 아침마다 체크하는 것들.CVE 최신 목록 OWASP 블로그 /r/netsec 서브레딧 보안 뉴스 사이트퇴근 후 루틴. 온라인 강의 듣기. HackTheBox, TryHackMe 문제 풀기. 보안 서적 읽기. 새 툴 테스트. 주말엔 CTF 대회. Capture The Flag. 해킹 경진대회. 세계 각국 화이트 해커들. 밤새워 문제 푼다. 작년에 팀 결성했다. "SeoulSec". 4명. 국내 대회 3등. 상금 300만원 나눴다. 돈보다 실력 향상이 목적. 자격증도 땄다. CEH (Certified Ethical Hacker) OSCP (Offensive Security Certified Professional) 다음은 CISSP 준비 중. 공부 안 하면 불안하다. 내가 모르는 공격 기법. 누군가는 알고 있다. 그걸로 우리 시스템 공격할 수 있다. 일상이 된 강박 이제 꺼낼 수가 없다. 보안 마인드셋. 일상에 스며들었다. 마트에서 카드 긁을 때. 단말기 확인한다. 스키밍 장치 없는지. 주변에 카메라 없는지. ATM 쓸 때도. 키패드 가린다. 뒤에 사람 확인. 카드 즉시 회수. 공공장소 USB 충전기. 절대 안 쓴다. Juice Jacking 가능. 보조배터리 항상 휴대. 여자친구와 여행. 호텔 WiFi 안 믿는다. 스마트 TV도 끈다. 카메라 가릴 수 있으면 가린다. "너무 예민한 거 아니야?" "직업병이야." "좀 쉬어." "이게 쉬는 거야." 집 현관 도어락. 지문 인식 안 쓴다. 비밀번호도 한 달마다 바꾼다. CCTV는 네트워크 분리. 스마트폰 설정. 불필요한 권한 다 껐다. 앱 최소한으로. 루팅 절대 안 함. "넌 편하게 못 살아?" 맞다. 못 산다. 하지만 안전하다. 그게 나한테는 편한 거다. 보안은 투자다 경영진 설득이 제일 어렵다. "보안에 얼마 들어갑니까?" "연 5억 정도 필요합니다." "매출에 기여는?" 설명한다. 보안은 비용이 아니다. 투자다. 보험이다. 사고 나면 손실이 더 크다. 데이터 유출 시. 고객 보상. 법적 대응. 브랜드 이미지 타격. 수십억 날아간다. 실제 사례 보여준다. 경쟁사 해킹 사고. 피해액 200억. 우리 보안 예산 5억. 40배 차이. "그래도 우린 안 당할 수도..." "100% 안전은 없습니다." "하지만 확률을 낮출 순 있습니다." "그게 제 일입니다." 설득 성공하면 예산 나온다. 새 보안 장비. 외부 모의해킹 용역. 직원 보안 교육. 다 필요한 것들. 실패하면 기존 예산으로 버틴다. 오픈소스 툴 활용. 직접 스크립트 짠다. 시간이 더 걸릴 뿐. 결과는 내야 한다. 보안 QA의 미래 이 일 언제까지 할까. 생각해본다. 보안 수요는 늘어난다. 클라우드, IoT, AI. 새 기술마다 새 위협. 일감은 줄지 않는다. 경력 쌓으면 선택지 많다. 보안 컨설턴트. CISO (Chief Information Security Officer). 보안 솔루션 개발. 강의, 집필. 나는 현장이 좋다. 직접 뚫어보는 재미. 취약점 찾는 쾌감. 시스템 지키는 보람. 10년 뒤엔? 팀장 되어 있을까. 후배 가르치고 있을까. 아니면 프리랜서? 확실한 건. 이 일은 평생 할 수 있다. 기술은 계속 배우면 된다. 열정만 있으면. 요즘 고민. 유튜브 채널 열까. '보안 QA의 일상'. 취약점 분석 영상. 보안 입문자 도움될 것 같다. 여자친구는 찬성. "네 얘기 재밌어." "근데 회사 기밀은 조심해." 알고 있다. 당연히. 그래도 이 일이 좋다 피곤하다. 스트레스 많다. 항상 긴장한다. 불안하다. 완벽할 수 없다. 한계 있다. 그래도. 취약점 찾았을 때. "이거 Critical입니다." 개발팀이 급히 고친다. 사고 막은 거다. 론칭 후 무사할 때. 아무 일 없이 서비스 돈다. 뉴스에 안 나온다. 내가 한 일이다. 고객들은 모른다. 내가 뭘 막았는지. 얼마나 위험했는지. 그래도 괜찮다. 화이트 해커. 선한 해커. 시스템 지키는 사람. 자부심 있다. 새벽 2시. 아직 모의해킹 중. Admin 권한 탈취 성공. "역시 여기 뚫리네." 리포트 쓴다. 재현 방법 상세히. 수정 방안까지. 책임감 있게. 내일 개발팀 회의. 또 설득해야 한다. "이거 고쳐야 합니다." 언제나처럼.취약점 찾는 게 일이지만, 없는 게 제일 좋은 일이다. 모순이지만 그게 보안이다.
- 03 Dec, 2025
'여기 인증이 빠졌는데요' - 개발팀이 싫어하는 문장 톱 3
"여기 인증이 빠졌는데요" - 개발팀이 싫어하는 문장 톱 3 오늘도 어김없이 오전 10시. 신규 API 보안 점검 중이다. POST 요청 날렸다. 토큰 없이. 200 OK 떴다. "아..." 이게 되면 안 되는 건데. 인증 헤더 빼고 다시 날렸다. 또 200 OK. 유저 정보 다 내려온다. 남의 거까지. 심장이 쿵 했다. 나쁜 의미로.슬랙 열었다. 개발팀 채널. "@김철수 API 인증 체크 부탁드립니다" 점잖게 썼다. 처음엔. 5분 뒤 답장. "어? 거기 인증 필요해요?" 필요하다. 매우. "네, 유저 정보 조회인데 인증 없이 호출 가능합니다" 또 5분. "아 그거요? 다음 스프린트에 넣을게요" 숨 참았다. 3초. "이거 지금 프로덕션인데, 남의 정보 다 보이는데..." "아 그래요? 근데 저 지금 급한 버그 픽싱 중이라..." 여기서부터 시작된다. 오늘의 전투. 1위: "여기 인증이 빠졌는데요" 6년 했다. 보안 QA. 이 문장 말하면 공기가 무거워진다. 개발자 표정이 굳는다. 매번. "인증이요...? 어디가요?" 다 알면서. "로그인 API에서 토큰 검증 안 하고 있습니다" "아..." 길게 늘어지는 '아'. 이게 시작이다. 반응은 보통 세 가지다. 첫 번째: 부정 단계 "그게 버그예요? 원래 그렇게 설계한 건데..." 아니다. 명세서 봤다. 인증 필수라고 써 있다. "명세서에 JWT 토큰 필수라고..." "아 그건 옛날 거고, 지금은 내부 API라서요" 내부? 인터넷에 열려 있는데? "퍼블릭 IP에서 호출 가능한데요" "아 그래요? 근데 URL 모르면 못 찾잖아요" URL이 보안이 되나. Obscurity는 보안이 아니다.두 번째: 협상 단계 "심각한 건 아니죠? P3 정도?" 심각하다. P1이다. "인증 없이 타인 정보 조회 가능하면 P1입니다" "어... 근데 실제로 악용된 사례는 없잖아요?" 없는 게 아니라 모르는 거다. 로그 분석 안 하니까. "로그 보면 알겠지만..." "로그요? 로그는 지금 안 보고 있는데..." 당연히. 세 번째: 지연 단계 "다음 주 배포 때 같이 넣을게요" 다음 주? 지금 뚫려 있는데? "핫픽스 가능할까요? 지금 취약점 열려 있어서..." "핫픽스요...? 그럼 배포 파이프라인 돌려야 하는데..." 그래야 한다. 보안 이슈니까. "CVSS 점수 8.2 나오는데요" 숫자 던졌다. 효과 있다. 가끔. "8.2요? 계산 어떻게 한 거예요?" 계산기 보여줬다. CVSS 계산기. Access Vector: Network Authentication: None Confidentiality Impact: High "아... 근데 저희 서비스 사용자가 적어서..." 사용자 수는 관계없다. 취약점은 취약점이다. 결국 타협했다. 내일 새벽 배포. 새벽 2시에 내가 테스트한다. 당연히. 2위: "이거 SQL Injection 되는데요" 이건 진짜 싫어한다. 개발자들. 왜냐면 '기초 중의 기초'니까. "부끄러운 거" 취급이다. 개발자 사이에서. 지난주에 찾았다. 검색 기능에서. GET /api/search?keyword=test' OR '1'='1500 에러 떴다. DB 에러 메시지 그대로. "MySQL syntax error near..." 심장이 또 쿵했다. 슬랙 DM 보냈다. 조용히. 이건 공개 채널에 쓰면 안 된다. 자존심 상한다. 개발자. "검색 API SQL Injection 취약점 있습니다. DM으로 상세 공유드릴게요" 읽음 표시 떴다. 2분 뒤. 답장은 30분 뒤. "확인했습니다. 근데 이거 관리자만 쓰는 기능이라..." 관리자도 해킹당한다. "관리자 계정도 타겟이 될 수 있어서요" "아... 근데 이미 Prepared Statement 쓰고 있는데..." 안 쓰고 있다. 코드 봤다. query = f"SELECT * FROM users WHERE name LIKE '%{keyword}%'"f-string 그대로. 교과서적 취약점. "코드 확인해보니 직접 문자열 조합하고 계시던데요" "아 그거요? 옛날 레거시 코드라..." 레거시면 더 위험하다. "고치기 어렵나요?" "어렵죠... 다른 데도 다 바꿔야 해서..." 얼마나 많길래. "몇 군데 정도?" "한... 20군데?" 20군데가 SQL Injection 가능하다고? 숨 참았다. 5초. "하나씩이라도 고쳐봐요. 일단 검색부터..." "네... 시간 나면..." 시간 나면은 안 한다는 뜻이다. 보통. 결국 JIRA 티켓 만들었다. P0로. CTO한테도 리포트 올렸다. 다음 날 핫픽스 나갔다. 역시 CTO. 개발자는 삐졌다. 일주일 동안. 점심 같이 안 먹자고 했다. 어쩔 수 없다. 보안이 먼저다.3위: "이 API 권한 체크가 없는데요" 이게 제일 미묘하다. 왜냐면 '작동은 한다'니까. 버그가 아니다. 기능 구현 누락이다. 근데 보안적으론 치명적이다. 지난달에 발견했다. 유저 삭제 API. DELETE /api/users/{user_id}로그인만 하면 된다. 누구나. 남의 계정도 지운다. 권한 체크 없으니까. 테스트했다. 내 계정 A로 로그인. 남의 계정 B를 삭제 요청. 204 No Content. 성공했다. "..." 슬랙 열었다. "@박영희 유저 삭제 API 권한 체크 필요합니다" 3분 만에 답장. 빠르다. "네? 권한이요?" "네, 지금 자기 계정 외에도 남의 계정 삭제 가능해요" "아 그거요? 원래 관리자용 API인데..." 관리자 체크 안 한다. 코드 봤다. "코드상 role 체크 없던데요" "어? 그래요? 근데 프론트에서 관리자만 버튼 보이게 해놨는데..." 프론트 제어는 보안이 아니다. curl 하나면 끝이다. "프론트 제어는 우회 가능해서요. 백엔드 체크 필요합니다" "아..." 또 길게 늘어지는 '아'. "근데 권한 체크 로직이 복잡해서... 시간이 좀..." 복잡하면 더 해야 한다. "IDOR 취약점이라 심각도 높습니다" "IDOR이 뭐예요?" 설명했다. Insecure Direct Object Reference. 객체 접근 권한 체크 안 하는 거. OWASP Top 10에 들어간다. "아... 그럼 언제까지 고쳐야 해요?" 이번 주. 가능하면 내일. "일주일 안에 가능할까요?" "일주일이요...? 다른 API도 다 체크해야 하는데..." 다 체크해야 맞다. "일단 삭제, 수정 API부터 점검해봐요" "네... 해볼게요..." 목소리에 힘이 없다. 2주 걸렸다. 결국. 20개 API 권한 체크 추가. 개발자는 지쳤다. 나도 지쳤다. 근데 해야 한다. 이게 우리 일이다. 개발자의 마음 이해한다. 어느 정도. 그들도 바쁘다. 매우. 기능 개발도 해야 하고. 버그 픽스도 쌓여 있고. 거기에 보안까지. "왜 이렇게 까다롭냐"고 한다. 가끔. 까다로운 게 아니다. 필수다. 해킹당하면 다 책임진다. 개발팀이. "보안팀 뭐했어?"도 들을 거다. 우리가. 그래서 미리 막는 거다. 근데 이게 충돌한다. 개발자의 우선순위:기능 개발 (PM이 독촉) 버그 수정 (유저 컴플레인) 성능 개선 (느리다고 항의) 보안 (음... 나중에?)보안 QA의 우선순위:취약점 수정 (지금 당장) 보안 강화 (예방) 기능은... 잘 모르겠고관점이 다르다. 개발자는 "될 때까지" 만든다. 우리는 "안 뚫릴 때까지" 뚫어본다. 방향이 반대다. 그래서 싸운다. 자주. 내가 하는 타협들 6년 하면서 배웠다. 말하는 방식이 중요하다는 것. 예전: "여기 인증 없는데요? 이거 왜 이래요?" 공격적이다. 비난처럼 들린다. 지금: "인증 체크 추가하면 더 안전할 것 같아요. 도움 드릴까요?" 부드럽다. 제안처럼 들린다. 효과가 다르다. 그리고 우선순위를 나눈다. P0: 지금 당장 (인증 누락, SQL Injection) P1: 이번 주 안에 (권한 체크) P2: 다음 스프린트 (보안 강화) P3: 여유 있을 때 (개선 사항) P0만 강하게 밀어붙인다. 나머지는 협상 가능하다. 그리고 직접 코드 짠다. 가능하면. "이렇게 고치면 될 것 같아요" PR 올린다. 리뷰 요청한다. 개발자가 좋아한다. 일이 줄어드니까. 같이 해결하는 거다. 싸우는 게 아니라. 그러면 관계가 좋아진다. 다음번에 또 취약점 보고할 때 덜 힘들다. 그래도 힘든 순간들 가끔은 진짜 화난다. 같은 취약점 반복될 때. "지난번에도 얘기했는데..." "아 그거요? 까먹었네요" 까먹을 일이 아닌데. 보안 가이드 문서 만들었다. 읽으라고 공유했다. 아무도 안 읽는다. "문서 어디 있어요?" 컨플루언스 첫 페이지다. "아 그거요? 나중에 볼게요" 나중은 오지 않는다. 그리고 사고 날 때. 실제 해킹 시도 있었다. DDoS는 아니고 credential stuffing. 로그인 시도 10만 건. 다행히 막았다. Rate limiting 있어서. 근데 그거 내가 추가한 거다. 3개월 전에. 그때도 "꼭 필요해요?"라고 물었다. 개발팀. 필요하다니까. 사고 후 회의. "다행히 보안 QA팀이 미리 조치해서..." 박수 받았다. 기분이 이상했다. 박수받을 일이 아닌데. 원래 있었어야 할 거니까. 그럼에도 계속하는 이유 취약점 찾았을 때. 희열이 있다. 정말. "이거다!" 심장 뛴다. 게임 깬 기분이다. 그리고 고쳐졌을 때. 다시 테스트한다. 인증 체크 들어갔다. 401 Unauthorized. 완벽하다. 뿌듯하다. 이 서비스가 조금 더 안전해졌다. 우리 유저들 정보가 지켜졌다. 밤에 잘 잔다. 마음 편히. CTF 대회 나갔다. 지난주. 1등 했다. Web 카테고리. 상금 100만원. 여자친구한테 자랑했다. "우리 남친 해커네~" 화이트 해커다. 강조했다. "맞아, 착한 해커" 기분 좋았다. 부모님한테도 말씀드렸다. "아들이 회사 보안 지키는 일 해요" "대단하네, 우리 아들" 뿌듯했다. 개발자들이랑 관계도 좋아졌다. 최근에. 술 먹었다. 회식에서. "야, 너 때문에 일 많아지긴 하는데..." 움찔했다. "고마워. 진짜로." "네?" "너가 안 잡아주면 우리가 욕먹잖아. 나중에." 인정받았다. 같이 일하는 거다. 결국. 적이 아니다. 동료다. 목표가 같다. 좋은 서비스 만들기. 앞으로의 계획 다음 달에 교육한다. 개발팀 대상 보안 교육. "Secure Coding 101" 준비 중이다. 자료. OWASP Top 10 중심으로. 실습도 넣을 거다. 직접 SQL Injection 해보기. 직접 XSS 공격 해보기. 체험하면 이해한다. 더 잘. 그리고 자동화 구축한다. CI/CD에 보안 스캔 넣기. SAST, DAST 돌리기. 커밋할 때마다 자동 체크. 내가 다 할 순 없으니까. 시스템이 해야 한다. 버그 바운티 프로그램도 열까 한다. 외부 화이트 해커들. 우리가 못 찾은 거 찾아주면. 포상금 주기. 더 안전해질 거다. CTO한테 제안할 거다. 다음 주. 오늘 마무리 6시다. 퇴근 시간. 근데 아직 못 끝냈다. 테스트. API 20개 더 남았다. 7시까지 해야겠다. 여자친구한테 문자 보냈다. "오늘 조금 늦을 것 같아. 저녁 먼저 먹어" "또? 무슨 취약점 찾았어?" "응, 인증 빠진 거" "개발자들 싫어하겠다 ㅋㅋ" 맞다. 근데 해야 한다. 이게 내 일이다. 화이트 해커. 좋은 해커. 서비스 지키는 사람. 모니터 3개 켰다. Burp Suite 실행. 다시 시작이다."여기 인증 빠졌는데요" 오늘도 말한다. 내일도 말할 거다.