홈택스 취약점 신고기: 오픈 리다이렉트부터 CVE·CWE까지
· dev· 6분
동료 SH님이 일하다가 홈택스 앱에서 이상한 동작을 하나 발견했습니다. “이거 신고해야 하는 거 아니야?” 했더니, 본인은 이런 귀찮은 건 안 한다고 하더군요. 그래서 제가 대신 해 보기로 했습니다.
준비하다 보니 “이런 건 어디에 어떻게 신고하지”, “CVE는 들어봤는데 CWE는 뭐지” 같은 걸 찾아보게 됐고, 알게 된 것들을 정리해 둡니다.
어떤 취약점이었나
홈택스는 웹 링크로 앱의 특정 화면을 열어 주는 앱링크(app link)를 씁니다. 문자나 알림의 링크를 누르면 홈택스 도메인을 거쳐 손택스 앱이 열리는 구조인데, 그 링크는 대략 이렇게 생겼습니다.
https://m.sefd.hometax.go.kr/appLink/?linkUrl=<이동할 주소>
linkUrl에 담긴 주소를 앱이 그대로 웹뷰에 띄웁니다. 문제는 이 값이 국세청 도메인인지 제대로 검증하지 않는다는 점이었습니다. linkUrl에 외부 주소를 넣어 보면, 손택스 앱이 정상적으로 열리면서 그 안에 전혀 상관없는 외부 사이트가 그대로 떴습니다.
이런 걸 오픈 리다이렉트(open redirect)라고 부릅니다. 신뢰받는 도메인이 검증 없이 사용자를 아무 데로나 보내 주는 취약점입니다. 하나만 놓고 보면 “그래서 뭐?” 싶지만, 무서운 건 피싱과 만났을 때입니다.
- 링크의 도메인은 진짜 국세청 것입니다(
m.sefd.hometax.go.kr,hometax.go.kr의 하위 도메인). 도메인만 보고 안심하는 사람에게는 완벽하게 정상으로 보입니다. - 그런데 최종적으로 열리는 건 공격자가 만든 가짜 로그인 화면일 수 있습니다.
- 게다가 그게 일반 브라우저가 아니라 국세청 앱 안에서 열립니다. 앱 껍데기가 주는 신뢰를 그대로 빌려 씁니다. 특히 손택스처럼 화면을 웹뷰로 그리는 앱이라면, 주소창도 없이 외부 페이지가 앱 화면처럼 보여서 더 위험합니다.
세금·환급 같은 미끼는 피싱에서 늘 잘 먹힙니다. 거기에 “정부 도메인 링크 + 정부 앱 화면”이라는 외피까지 붙으면, 평소 조심하던 사람도 넘어갈 만합니다. 반면 막는 방법은 그리 복잡하지 않습니다. linkUrl을 파싱해 스킴이 HTTPS인지, 호스트가 허용된 국세청 도메인 목록(화이트리스트)에 있는지 확인하고, 아니면 열지 않도록 막으면 됩니다.
국세청 ‘개선완료’ 답변

국민신문고로 접수한 뒤 받은 국세청의 ‘개선완료’ 답변. 담당자 실명·연락처는 가렸습니다.
보안 취약점은 어디에 신고하나
막상 접수하려니 창구부터 헷갈렸습니다. 이번에 알아본 창구는 크게 세 곳입니다.
- 국가사이버안보센터(NCSC, ncsc.go.kr) — 국가·공공기관 관련 사이버 위협을 다루는 곳입니다. 홈페이지에 취약점 신고 창구가 있어서, 여기에 재현 절차·원인·영향을 적어 접수하고 재현 영상은 안내된 메일로 따로 보냈습니다.
- 국민신문고(epeople.go.kr) — 정부 민원 포털입니다. 보안 전용 창구는 아니지만, “홈택스”라는 특정 기관 서비스의 문제라 여기로도 민원을 넣었습니다. 이렇게 접수하면 담당 기관으로 배정되는데, 실제로 처리기관이 국세청으로 지정돼 답변이 돌아왔습니다. 기관 서비스의 문제를 그 기관에 직접 닿게 하는 데는 이 경로가 가장 확실했습니다.
- KISA 보호나라 & KrCERT(boho.or.kr) — 이번엔 안 썼지만 알아 두면 좋습니다. 소프트웨어 제품의 신규 취약점을 신고받고 포상하는 제도(신고포상제, 일종의 버그 바운티)를 운영합니다. 특정 기관이 운영하는 웹 서비스 문제보다는, 널리 쓰이는 제품·솔루션의 취약점에 어울리는 창구입니다.
정리하면, 공공·정부 기관의 서비스 문제라면 그 기관에 닿는 경로(국민신문고·NCSC)를, 널리 배포되는 제품의 취약점이라면 KISA를 쓰면 됩니다. 민간 서비스라면 해당 업체의 공식 보안 신고 채널을 먼저 확인하는 게 맞습니다. 참고로 저는 NCSC와 국민신문고 두 곳에 모두 넣었는데, ‘개선완료’ 회신은 국민신문고(처리기관 국세청)를 통해 돌아왔습니다.
CVE와 CWE
신고서를 쓰다 보니 근거를 대야 했고, 그러다 CVE와 CWE를 처음으로 구분하게 됐습니다. SI 프로젝트를 할 때 고객사에 컨테이너 이미지를 넘기기 전 Trivy로 취약점을 검사하곤 해서 CVE는 익숙했지만, CWE는 이번에 처음 제대로 들여다봤습니다.
CVE(Common Vulnerabilities and Exposures)는 특정 제품·버전에서 발견된 개별 취약점 하나하나에 붙는 고유 번호입니다. 예를 들어 Log4Shell에는 CVE-2021-44228이라는 번호가 붙어 있습니다. “이 문 하나가 열려 있었다”는 사건 번호에 가깝습니다.
CWE(Common Weakness Enumeration)는 취약점을 유형별로 정리한 분류 사전입니다. 이번에 신고한 오픈 리다이렉트는 CWE-601에 해당합니다. 개별 사건이 아니라 “문을 안 잠그는 실수”라는 분류에 가깝습니다.
그래서 하나의 CVE(구체적 사건)에는 보통 하나 이상의 CWE(원인 유형)가 태깅됩니다. 반대로 제가 신고한 건은 CWE-601 유형이긴 해도 CVE 번호는 붙지 않았습니다. CVE는 주로 배포·판매되는 소프트웨어 제품에 발급되다 보니, 특정 기관이 운영하는 이런 서비스 건에는 잘 붙지 않습니다.
실제로 오픈 리다이렉트(CWE-601)로 분류된 CVE로는 Directus의 CVE-2024-28239, caddy-security의 CVE-2024-21497 같은 사례가 있습니다. 같은 유형(CWE)에 이렇게 여러 사례(CVE)가 달리는 구조를 그림으로 보면 이렇습니다.
CWE-601(오픈 리다이렉트) 같은 ‘유형’ 하나에는 여러 CVE(개별 ‘사례’)가 달립니다. 이번 홈택스 건처럼 CVE 번호가 붙지 않은 취약점도 같은 유형에 속하고요(1 : 0..N). 심각도는 CVSS 점수로 따로 가늠합니다.
찾아보니 이런 분류·평가 체계가 더 있었습니다.
- CVSS (Common Vulnerability Scoring System) — 취약점의 심각도를 0.0~10.0 점수로 매기는 표준.
- CWE Top 25 — MITRE가 매년 발표하는 “가장 위험한 소프트웨어 약점 25가지”.
- OWASP Top 10 — 웹 애플리케이션에서 특히 자주·심각하게 나타나는 보안 위험 목록. 실무에서 체크리스트처럼 많이 씁니다.
- CAPEC (Common Attack Pattern Enumeration and Classification) — 약점을 실제로 어떻게 공격하는지, 공격 패턴을 정리한 사전.
- CISA KEV (Known Exploited Vulnerabilities) — 실제로 악용이 확인된 취약점 목록. 패치 우선순위를 정할 때 쓰입니다.
CVE·CWE·CVSS만 구분해도 “어떤 유형의 실수로(CWE) 어디서 터졌고(CVE) 얼마나 위험한지(CVSS)“라는 큰 틀이 잡힙니다.
마무리
대단한 걸 찾은 것도, 제가 찾은 것도 아닙니다. 동료가 무심코 발견한 걸 대신 신고했을 뿐입니다. 그래도 “이상하다” 싶은 걸 그냥 지나치지 않고 제대로 된 창구로 흘려보내는 걸 한 번 해 두니, 다음엔 덜 망설일 것 같습니다. 제가 만드는 서비스에서 링크를 받아 어딘가로 보내는 코드를 짤 때도 목적지 검증 한 번을 꼭 떠올리게 될 것 같고요. 그리고 뭔가 미심쩍은 게 보이면 그냥 넘기지 않고, 늘 쓰던 도구에 더해 AI에게도 한번 봐 달라고 맡겨 볼 생각입니다.
여담으로, 아쉽게도 보상금 같은 건 없었습니다. 국세청에서 ‘개선완료’ 회신 한 통이 전부였죠. 뭐, 바라고 한 일은 아니었으니 그걸로 됐습니다.