[문제어때] 보안 하드닝과 외부 링크 처리에 대한 고민

최은창·2026년 2월 13일
post-thumbnail

최근 Electron 애플리케이션에서 보안 하드닝 작업을 진행했다.

기존 구조에서는 Renderer Process와 Main Process 사이에 명확한 샌드박스 설정이 적용되어 있지 않았고, 이 점이 계속 신경 쓰였다. 이번 작업을 계기로 해당 부분을 정리하며 보안 설정을 강화했다.

Electron에서 Renderer Process는 사실상 클라이언트 영역에 가깝다.

어떤 입력이 들어올지, 어떤 코드가 실행될지 예측할 수 없는 영역이기 때문에 최소한의 권한만을 허용하는 안전 지대(Sandbox) 설정이 필수적이라고 판단했다. 이번 업데이트의 핵심 역시 이 Sandbox 설정이었다.

Sandbox라는 단어를 떠올리면 개인적으로 ActiveX가 생각난다. (여담이다)

Windows XP 시절에는 거의 모든 환경에서 사용되던 기술이었고, 당시에는 위험하다는 인식조차 희미했다. 지금 기준으로 보면 과도한 권한을 사용자 환경에 그대로 노출한 굉장히 위험한 구조였고, 돌이켜보면 꽤 아찔한 방식이었다는 생각이 든다.

이번 작업에서는 Sandbox 설정을 적용하고, Renderer Process에서의 Node API 접근 권한 또한 제거하면서 하나의 보안 작업을 마무리했다.

외부 URL을 어떻게 처리할 것인가

다음으로 고민하게 된 주제는 외부 URL 처리 방식이었다.

Electron 앱에서 외부 링크를 클릭했을 때,

  • 애플리케이션 내부에서 열 것인지
  • 아니면 시스템에 설정된 기본 브라우저로 넘길 것인지

이 선택은 단순히 구현 문제가 아니라 보안과 UX의 균형에 대한 고민이었다.

1. 외부 브라우저로 실행하는 방식

가장 안전한 방법은 외부 브라우저로 링크를 실행하는 것이다.

보안 관점에서는 추가적인 고민이 거의 필요 없을 정도로 안정적인 선택이다.

하지만 이 방식에는 명확한 단점이 있다.

애플리케이션에서 링크를 클릭했는데 전혀 다른 프로세스(브라우저)가 실행되면서, 사용자가 앱의 흐름에서 벗어나게 된다.

물론 “그게 뭐가 문제냐”고 생각할 수도 있다.

하지만 개인적으로는 하나의 앱 안에서 이루어지던 경험이 갑자기 끊기면서, 사용자가 앱 외부로 튕겨 나가는 느낌을 받는다는 점이 마음에 걸렸다.

모바일 환경에서는 외부 링크를 브라우저로 넘기는 경우가 많아 이제는 자연스럽지만, 데스크톱 애플리케이션에서는 불필요한 프로세스를 하나 더 띄우는 행위처럼 느껴졌다. 특히 사용중인 앱 외에 새로운 무언가를 실행한다는 점에서 UX가 깨진다는 인상을 받았다.

2. 또 하나의 Renderer Process로 실행하는 방식

두 번째 방법은 앱 내부에서 새로운 Window를 띄워 외부 사이트를 보여주는 방식이다.

모달은 아니지만 같은 애플리케이션 안에서 창을 하나 더 여는 구조로, UX 측면에서는 상당히 자연스럽다.

문제는 보안이다.

Node API 권한도 제거했고 preload 노출도 최소화했지만, 만약 피싱 사이트에서 preload를 타겟으로 XSS 공격을 시도한다면 충분히 공격 시나리오가 만들어질 수 있다.

현재 애플리케이션이 다루는 데이터가 크리티컬하지 않다고 하더라도,

“공격이 가능하다”는 사실 자체가 이미 보안 위협이다.

사용자가 어떤 데이터를 다루느냐에 따라 위험도는 언제든 달라질 수 있기 때문에 이 가능성을 간과할 수는 없었다.

정리해보면

  • 외부 브라우저로 실행
    → 보안적으로는 안전하지만 UX가 저해된다.
  • 또 하나의 Renderer Process로 실행
    → UX는 자연스럽지만 보안 리스크가 존재한다.

내가 선택한 방향

보안을 무조건 실버 불릿처럼 여기고 모든 것을 차단하는 선택은 하고 싶지 않았다.

그래서 현재 애플리케이션의 실제 사용 시나리오를 다시 살펴봤다.

우리 앱에서 외부 링크는 사실상 GitHub 하나뿐이다.

그 외의 도메인은 의도적으로 연결하지 않고 있다.

다만 GitHub 내부 링크를 통해 다른 외부 도메인으로 리다이렉션되는 경우는 충분히 발생할 수 있다.

그래서 위협 요소를 조금 더 명확하게 구분해보기로 했다.

우리 앱이 가장 취약한 시나리오는 다음과 같을 것이다.

이 흐름을 기준으로 생각해보면,

  • GitHub 도메인 내부에서는 Renderer Process로 실행하고
  • GitHub를 통해 이동되는 외부 도메인이나, 그 외의 외부 링크는 시스템 브라우저로 실행한다

라는 정책이 가장 합리적인 선택이라고 판단했다.

이렇게 하면 우리가 의도한 링크에서는 UX를 해치지 않으면서도,

통제되지 않는 외부 사이트에 대해서는 안전하게 격리할 수 있다.

물론 이 선택에는 트레이드 오프가 존재한다.

GitHub 도메인 내 XSS 이슈나 보안 취약점에 대해서는 지속적인 모니터링이 필요해졌고, 관리 포인트 또한 늘어났다.

마무리하며

최근 “실버 불릿은 없다”라는 말을 들었다.

모든 상황에 완벽하게 맞는 기술이 없듯이, 보안 역시 무조건 최고 수준으로 적용하는 것이 항상 정답은 아닐 수 있다.

어떤 맥락에서는 그것조차 오버 엔지니어링이 될 수 있다.

그래서 앞으로도

“이 선택이 정말 필요한가?”

“지금 내가 실버 불릿을 믿고 있는 건 아닌가?”

이 질문을 스스로에게 계속 던지면서 개발을 이어가고 싶다.

profile
비슷한 어려움을 겪는 누군가에게 도움이 되길

0개의 댓글