Skip to content

남겨두는 레거시 코어 ​

회사 레거시 코어에 의심스러운 요청들이 스캔되었다.

대략적인 패턴은 이랬다. 공격자는 프론트엔드 화면에서만 숨겨진 회원가입 요청으로 인증된 계정을 쉽게 생성했고, 프론트엔드 화면에서 사용 중인 경로를 파악해 IDOR 탐색 및 인증 없이 호출할 수 있는 다른 경로까지 찾아냈다. Swagger API 문서에는 노출되지 않았으나 /v3/api-docs?에 파라미터를 지정하니 백엔드 경로가 그대로 응답되었다.

외부 도메인이 연결된 레거시 코어 ​

최근에 만들어지던 다른 신규 서비스 제품들의 기반이 되었으나, 기존에 외부로 제공되어 있던 도메인이 그대로 남아 방치된 결과다. 해당 코어는 외부에서 접근할 일이 없는데도 기존 레거시 화면을 닫지 않고 열어둔 것이 화근이었다.

오래된 레거시 도메인인 데다 회사 홈페이지를 개편하면서 제품 소개 링크까지 함께 노출해 두었다. 공격자가 마음만 먹으면 시스템의 존재를 쉽게 알아차릴 수 있는 상태였다.

최근 공격자들이 모든 기업이 제공하는 서비스 도메인을 스캔해 취약점을 조사하고 개인정보를 수집하는 패턴이 도드라지고 있다. 기업 임직원 교육을 담당하던 멀티캠퍼스, 기업 안에서 사용하는 메신저를 제공하는 카카오워크, 2주 새 두 번이나 해킹당한 마이리얼트립, 내부 관리 시스템이 뚫린 쏘카까지 잇따라 침해되었다. 현재 발생 중인 MS 아웃룩 오류도 AI 에이전트 공격을 의심하지 않을 수 없다.

개인정보 유출 기사를 자세히 살펴보면 대부분 외부 접근 경로를 차단했다고 밝힌다. 그만큼 SSRF나 IDOR 취약점을 가진 경로가 남아 있는 레거시 시스템이 많다는 뜻이다. 보안 검토를 아예 안 한 게 아니라 몰라서 넘어가는 부분이 많다는 것으로 보인다.

우리만 모르고 있다 ​

사내 제품에서 사용되지 않는 경로와 취약할 가능성이 있는 부분, 그리고 인프라 설정이 이상한 부분을 공유해도 그동안 "우리만 알고 있자구요" 라며 쉽게 넘어갔다.

레거시 화면의 개발 패턴은 백엔드 경로들을 UrlMap 형태로 내려주고 프론트엔드에서 키로 꺼내 쓰는 구조로 만들어져 있었다. 이걸 다른 개발자들은 몰랐다고 한다(심지어 초기 구성했던 개발자들도).

역할별로 필요한 API만 주지 않고 모든 사용자에게 전체 엔드포인트 정보를 내려주고 있었다. 공격자가 로그인하면서 Url Mappings 정보까지 한꺼번에 노출된 것으로 보인다.

다행히 개인정보 같은 사용자 정보가 조회된 건 아니다. 다만 수많은 요청 경로 중 인증이 없거나 권한 검사 없이 통과되는 IDOR 경로가 더 남아 있을 수 있다. 해당 레거시 코어에는 다른 서비스를 쉽게 호출하려고 만들어 둔 프록시 경로도 있었는데, 프록시라는 요청 경로가 확인되면 공격자는 SSRF 가능성을 보고 여러 가지 시도를 한다. 심지어 클로드 모델을 제공하는 앤트로픽마저 취약한 경로를 만들어 내고 모른다.

잘 알려진 공격 표면들 ​

/health, /swagger-ui.html 등 일반적으로 웹 애플리케이션에서 제공되는 경로들은 널리 알려져 있어 외부에서 쉽게 호출을 시도한다. Spring Boot Actuator 같은 모니터링 경로의 노출 설정도 인프라 레벨에서 신경 써야 한다. 예를 들어 신규 서비스가 Spring Boot 3로 만들어져 일부 마스킹이 자동으로 적용된 반면, 레거시 스택이 Spring Boot 2라면 env와 heapdump 엔드포인트가 마스킹되지 않고 그대로 노출될 가능성이 높다.

다행히 레거시 코어는 우아한형제들 기술블로그의 Actuator 보안 글을 참고해 위험한 엔드포인트가 활성화되지 않도록 막아두었다. 하지만 새로 만들어지는 프로젝트들은 추가한 개발자들이 이를 신경 쓰지 않았던 것으로 보인다.

파이썬 FastAPI 기반으로 만들어진 프로젝트들은 신경 쓰지 않았는지 API 문서 경로가 기본으로 활성화되어 있는 상태였다. 로컬이나 테스트 용도로 잠깐 만들어서 호출한다고 생각했던 경로들이 그대로 커밋되어, 외부 공격자도 인증 없이 호출할 수 있다는 걸 알아낸다. 외부에서 접근할 수 있는 도메인이 연결되거나 SSRF로 직접 요청될 수 있는 경로가 확보되면 위험해진다.

우리는 바쁘니까 ​

새로운 서비스 제품만 고민하다 보니 기존 레거시 코어의 미사용 기능과 취약 경로는 "바쁘니까" 라는 말로 방치해 왔다. AI 에이전트를 활용할 수 있는데도 레거시 문제를 직접 살펴보지 않은 점이 근본적인 원인이다(문제를 찾으면 조치는 우리 몫이니까). 게다가 AI 에이전트가 짚어주는 무분별한 지적을 고치고 다시 묻기를 반복하다 보면 불필요한 커밋만 수두룩 쌓이기도 한다.

티빙 개발자 토큰 유출 사례나 민감 정보 커밋 사고가 이어져도, 운영 중이지 않은 저장소는 방치하고 유지보수 중인 저장소는 과거 이력을 둔 채 삭제 커밋만 올린다. 나 역시 10년 차가 되고 인원이 줄면서 조직의 모든 저장소를 볼 수 있는 권한을 갖게 되었는데, 이런 개발자 토큰이 유출되면 커밋 이력에 남은 하드코딩된 JWT 서명 키와 토큰이 모두 조회된다. 민감 정보는 커밋에서 지우는 데 그치지 말고 키와 토큰 자체를 새로 교체해야 한다.

더 큰 문제는 레거시 프로젝트의 결함을 방치한 채 취약한 코드 베이스를 그대로 복제 해 새 프로젝트를 시작하기도 한다는 점이다. AI 에이전트 역시 따로 지시하지 않으면 저장소 전체의 보안 문제를 먼저 알려주지 않는다.

새로운 기술 스택을 위에 덧대기 전에 기존 레거시 코어부터 돌아봐야 한다. 정말로 사용되지 않을 경로들은 숨기지 말고 명시적으로 삭제 하는 게 좋다.

Released under the MIT License.