[web]LLM을 통한 웹페이지 난독화 분석(…작성중)

[web]LLM을 통한 웹페이지 난독화 분석(…작성중)

태그
생성 일시
Mar 27, 2025 10:40 AM
최종 편집 일시
Last updated May 19, 2025
Date

개요

웹 개발에서 '클라이언트를 신뢰하지 말라'는 격언은 널리 알려져 있다. 허술하게 구축된 백엔드도 위험하지만, 태생적으로 보호의 담장 밖에 노출된 프론트엔드의 정보는 본질적으로 백엔드보다 더 취약할 수밖에 없다. 이에 더불어, 전통적인 프론트엔드의 구조적 한계를 극복하기 위해 등장한 SPA(Single Page Application) 방 식은 다양한 기능을 가능하게 했다. 그러나 기능이 확장될수록 보안에 신경 써야 할 영역도 함께 증가했다. 체계적인 상태 관리부터 백엔드 서버와의 원활한 연동까지, 현대 프론트엔드는 단순한 정보 전달자를 넘어 백엔드 서버로의 관문 역할을 수행하게 되었다. 이러한 변화는 프론트엔드에 더 큰 책임을 부여했고, 자연스럽게 프론트엔드 코드 분석을 어렵게 하는 난독화 솔루션이 주목받게 되었습니다. 이 글에서는 현재 운영 중인 서비스에 난독화 솔루션을 적용하고, LLM을 활용하여 이러한 코드의 복호화가 어디까지 가능한지 탐구한 과정을 소개하겠습니다.

SSR에서 CSR/SPA로의 변화

웹 개발은 초기에 서버가 완성된 HTML 문서를 생성하여 클라이언트에게 전달하는 방식으로 시작되었다. 그러나 웹 서비스가 발전함에 따라 정적 콘텐츠를 넘어 사용자별 맞춤형 동적 콘텐츠의 필요성이 커졌다.

렌더링 패러다임의 진화

이러한 변화는 두 가지 접근 방식을 가져왔다:
  1. 서버 사이드 렌더링(SSR): 서버가 완전한 HTML을 구성하여 클라이언트에게 전달
  1. 클라이언트 사이드 렌더링(CSR): 서버는 최소한의 데이터만 제공하고, 클라이언트가 JavaScript를 통해 DOM을 구성
SSR은 서버 자원을 더 많이 소모하는 반면, CSR은 클라이언트 디바이스에 더 많은 부담을 준다. 현대 기기의 성능 향상과 더욱 인터랙티브한 웹 경험에 대한 요구로 인해, 많은 웹 서비스들이 자연스럽게 CSR 방식을 채택하게 되었다.

SPA의 등장과 의미

CSR의 발전은 "단일 페이지 애플리케이션(SPA)" 개념으로 이어졌다. 전통적인 웹사이트는 각 페이지마다 별도의 HTML 파일을 요청해야 했지만, SPA는 초기 로딩 후 페이지 전환 시 필요한 데이터만 비동기적으로 가져와 화면을 갱신한다. 이는 사용자 경험을 향상시키고 불필요한 네트워크 요청을 줄여준다.

진화의 타임라인

웹 개발 패러다임의 진화를 살펴보면:
  • 초기: 정적 HTML 페이지 제공
  • 중기: 서버에서 동적으로 HTML 생성 (전통적 SSR)
  • 과도기: AJAX를 통한 부분적 클라이언트 렌더링
  • 현재: 클라이언트가 전체 UI를 관리하는 SPA 방식

새로운 관리 포인트와 보안 고려사항

프론트엔드가 독립적인 시스템으로 발전하면서, 여러 새로운 관리 포인트가 등장했다:
  1. DOM 조작 보안: 클라이언트에서 동적으로 DOM을 구성함에 따라 콘텐츠 변조 위험이 증가
  1. 인증 및 권한 관리: 서버 내부에서만 관리되던 인증 정보가 이제는 클라이언트와 공유되어야 하는 범위가 확대
  1. 민감 정보 처리: 결제, 인증, 외부 API 연동과 같은 민감한 기능들이 "제3자 서버 → 백엔드 → 프론트엔드" 경로로 노출되는 표면이 확대
  1. 상태 관리의 복잡성: 페이지 전환 없이 애플리케이션 상태를 일관되게 유지해야 하는 새로운 과제
이러한 변화는 서버 부담을 줄이고 사용자 경험을 향상시켰지만, 동시에 보호 장벽 밖에 있는 클라이언트에 더 많은 권한과 책임을 부여함으로써 새로운 보안 과제를 가져왔다.

난독화란 무엇인가?

프론트엔드 영역이 확대되면서 관리해야 할 보안 표면 또한 늘어났다. 이에 따라 다양한 보안 대책들이 등장했고, 이번 포스팅에서는 그중 코드 분석을 어렵게 하는 난독화(Obfuscation)에 대해 다루고자 한다.
난독화는 코드의 가독성을 의도적으로 떨어뜨려 분석과 리버스 엔지니어링을 어렵게 만드는 보안 기법이다. 이는 특히 소스 코드가 외부에 노출되는 웹 프론트엔드 영역에서 효과적인 보호 수단으로 활용된다.

난독화가 필요한 이유

웹 애플리케이션은 근본적으로 클라이언트에 소스 코드가 전달되는 구조를 가진다. 따라서 사용자는 물론 잠재적 공격자 역시 쉽게 클라이언트 측 소스 코드에 접근할 수 있다. 공격자는 코드를 분석하여 로직을 이해하거나 취약점을 발견하고, 이를 악용할 수 있다. 본래의 소스 코드가 명확할수록 분석이 쉬워지므로, 코드 난독화는 공격자의 분석 비용을 높이게 된다.
실제로 이 포스팅의 출발점도 직관적으로 하드코딩된 수많은 조건문으로 구성된 소스코드를 접하고 난 뒤였다.
/** so.cool.com(product) **/ if(url.hostname == "so.cool.com") { ... } . . . /** so.cool300.com(test) **/ if(url.hostname == "so.cool300.com") { ... }
이러한 코드는 분석자에게 너무나 명확하게 로직과 구조를 전달해 주며, 공격자가 쉽게 이해할 수 있는 단서를 제공한다.

난독화의 목적과 효과

난독화의 주된 목표는 코드의 의미적 기능을 유지한 채 코드 분석을 어렵게 만드는 것이다. 이는 코드의 가독성을 낮추고, 변수와 함수명을 의미 없는 문자열로 대체하거나, 흐름을 복잡하게 변형하여 분석자의 이해를 방해한다.
주요한 효과는 다음과 같다:
  • 분석 비용 증가: 공격자가 코드를 분석하고 취약점을 찾는 데 소요되는 시간과 노력을 증가시킨다.
  • 지적 재산권 보호: 알고리즘과 핵심 비즈니스 로직과 같은 기업의 중요한 자산을 보호할 수 있다.
  • 공격 난이도 상승: 공격자가 로직을 쉽게 파악할 수 없어, 보안 위협의 현실적 가능성을 낮추게 된다.

난독화를 적용해 보자

현재 적용할 서비스는 vite를 번들러로 활용한다. vite는 빌드시 번들 용량 최적화를 위해 함수 및 변수명 단순화를 통한 기본적 난독화 기능이 구현되어 있다. 그러나 문자열에 대한 난독화 처리는 지원하지 않고 있는데, 이로 인해 DOM 내 텍스트 요소를 통해 해당 페이지의 렌더링 소스코드를 쉽게 식별할 수 있다.
notion image
DOM렌더링에 사용되는 요소는 평문으로 설정이 되어 있다.