플러그인 시스템의 딜레마: 확장성과 보안 사이 morgan021 2025. 11. 24.
> _
나의 작고 소중한 세계에 타인을 들이는 일
주말 저녁, 근사한 홈 파티를 열었다고 상상해 보자. 너른 거실은 세련된 조명으로 빛나고, 엄선한 플레이리스트가 흐른다. 그런데 초대받은 손님 중 누군가가 불쑥 주방으로 들어가더니, 자기가 가져온 정체불명의 식재료로 요리를 시작한다면 기분이 어떻겠나. 그 요리가 미슐랭 3스타급의 걸작일 수도 있다. 하지만 그 과정에서 아끼던 그릇을 깨뜨리거나, 최악의 경우 주방을 홀라당 태워먹을 수도 있는 노릇이다.
소프트웨어 개발의 세계에서 '플러그인(Plugin)'을 허용한다는 건 바로 이런 딜레마와 마주하는 일이다. 피그마(Figma)나 VS Code 같은 도구들이 위대한 이유는 개발사가 미처 생각하지 못한 기능들을 사용자가 직접 만들어 붙일 수 있게 문을 활짝 열어두었기 때문이다. 하지만 여기엔 치명적인 모순이 숨어 있다. "내 앱에서 당신의 코드를 실행하게 해주세요"라는 요청은, 보안 담당자 입장에선 "내 심장에 당신의 칼을 꽂아보세요"라는 말과 다를 바 없게 들린다. 사용자가 만든, 검증되지 않은 코드를 내 안방에서 실행한다는 건 미친 짓이거나, 아니면 세상을 바꿀 혁신이거나, 둘 중 하나다.
이 위험한 줄타기를 성공시키기 위해 아키텍처 설계자들은 밤새워 고민한다. 어떻게 하면 남이 만든 코드를 내 품에 안으면서도, 내 지갑과 데이터를 안전하게 지킬 수 있을까. 이것은 단순한 기술의 문제가 아니다. 신뢰할 수 없는 대상을 신뢰할 수 있는 환경에서 돌려야 하는, 고도의 심리전이자 철학적인 문제다.

유리벽 너머의 대화, 아이프레임의 고독
가장 전통적이고 확실한 방법은 손님을 별채에 가두는 것이다. 웹 개발의 세계에서는 이것을 '아이프레임(Iframe)'이라고 부른다. 아이프레임은 본채(메인 앱)와는 완전히 분리된 별도의 공간이다. 그 안에서 플러그인이 춤을 추든 노래를 하든, 메인 앱의 DOM(문서 객체 모델)이나 CSS 스타일에는 손끝 하나 댈 수 없다. 완벽한 격리다.
하지만 이 방식은 너무나도 고독하다. 별채에 있는 손님과 대화를 하려면, 창문을 열고 고래고래 소리를 질러야 한다. 기술 용어로는 '포스트 메시지(postMessage)'라고 하는 통신 방식인데, 이게 생각보다 비용이 비싸다. 데이터를 주고받을 때마다 직렬화와 역직렬화라는 번거로운 포장 과정을 거쳐야 하기 때문이다.
게다가 사용자 경험(UX) 측면에서도 꽝이다. 사용자는 물 흐르듯 자연스러운 경험을 원한다. 버튼을 눌렀는데 한 박자 늦게 반응하거나, 팝업창이 뚝뚝 끊겨서 뜬다면 누가 좋아하겠나. 아이프레임은 안전하지만, 그만큼 무겁고 느리다. 마치 면회실 유리벽을 사이에 두고 수화기로 대화하는 것처럼, 답답하고 거리감이 느껴지는 방식이다. 혁신을 위해서는 조금 더 과감한 접촉이 필요하다.
한 이불 덮고 자는 위험한 동거, SES
그래서 등장한 것이 SES(Secure ECMAScript)다. 이것은 손님을 안방으로 들이되, 손발을 묶어두는 방식이다. 같은 자바스크립트 스레드 위에서 돌아가니 속도는 비할 데 없이 빠르다. 데이터 전송 비용도 거의 없다. 옆에 앉아서 속삭이는 것과 같다.
하지만 낯선 이와 한 이불을 덮는 건 역시나 위험하다. 자바스크립트는 본래 매우 자유분방한 언어다. 마음만 먹으면 전역 객체를 오염시키거나, 프로토타입을 조작해 시스템 전체를 교란할 수 있다. SES는 이런 위험 요소를 원천 봉쇄한다. lockdown()이라는 강력한 주문을 외워, 객체들을 얼려버리고(Freeze) 위험한 기능들은 아예 접근조차 못 하게 막는다.
문제는 DOM 접근 제어다. 화면을 그리는 권한을 주지 않으면 플러그인은 뇌만 있고 손발이 없는 상태가 된다. 그렇다고 덜컥 권한을 줬다간 사용자의 클릭을 가로채거나 가짜 화면을 띄워 정보를 탈취할 수도 있다. 빠르고 효율적이지만, 그만큼 다루기가 까다로운 야생마 같은 존재다. 보안을 위해 성능을 포기할 것인가, 성능을 위해 위험을 감수할 것인가. 선택의 기로에서 아키텍처는 진화한다.
방폭실 안에 수갑 찬 천재를 가두다
여기서 천재적인 절충안(?) 비슷한 게 등장한다. 바로 아이프레임과 SES를 결합하는 하이브리드 전략이다. 상상해 보자. 튼튼한 방폭 유리로 지어진 독방(Iframe)이 있다. 그 안에 천재 해커(Plugin Code)를 가둔다. 그리고 그냥 두는 게 아니라, 그 해커에게 수갑(SES)까지 채운다.
이것은 이중 방어막이다. SES는 코드 레벨에서 자바스크립트 객체에 대한 무단 접근을 막는다. 만에 하나 SES가 뚫리더라도, 그 바깥에는 아이프레임이라는 물리적(논리적) 격리벽이 버티고 있다. 심지어 이 아이프레임은 sandbox 속성으로 중무장해서, 폼 제출이나 팝업 생성 같은 수상한 짓은 꿈도 못 꾸게 만든다.
이 구조에서 플러그인은 마음껏 자신의 천재성을 발휘할 수 있다. 연산은 빠르고, 로직은 자유롭다. 하지만 그 결과물이 바깥세상, 즉 사용자의 지갑이나 메인 앱에 영향을 미치려면 반드시 정해진 통로(RPC)를 통해 허락을 받아야 한다. "이봐, 나 계산 다 끝났는데 결과 좀 보여줘도 돼?"라고 물어보면, 메인 앱이 검토 후 "오케이, 보여줘"라고 승인하는 식이다. 이것이 바로 확장성과 보안이라는 두 마리 토끼를 잡는 묘수다.
꼬리에 꼬리를 무는 의심, 공급망의 위협
하지만 적은 내부에만 있는 게 아니다. 플러그인 개발자가 아무리 선량하다 해도, 그가 가져다 쓴 제3의 라이브러리가 악성일 수도 있다. 오픈 소스 생태계의 축복이자 저주다. npm install 한 번으로 수많은 코드가 딸려 들어오는데, 그중 하나라도 썩은 사과가 섞여 있다면?
이때 필요한 것이 '라바모트(LavaMoat)' 같은 도구다. 이것은 일종의 세관 검사관이다. 플러그인이 사용하는 모든 외부 패키지를 샅샅이 뒤져서, 각 패키지가 어떤 권한을 요구하는지 분석한다. "이 날씨 앱 라이브러리가 왜 내 파일 시스템에 접근하려고 하지?" 같은 수상한 정황이 포착되면 즉시 차단한다.
우리는 종종 보안을 성벽을 높게 쌓는 것으로 착각한다. 하지만 진정한 보안은 성은 드나드는 모든 물자를 추적하고 통제하는 시스템에 있다. 플러그인 시스템 아키텍처는 그렇게 단순히 코드를 실행하는 것을 넘어, 그 코드가 어디서 왔고 누구와 어울리는지까지 감시해야 한다. 믿음은 좋지만, 확인은 필수니까.
60fps의 우아함을 잃지 않으려면
이 모든 보안 장치를 주렁주렁 매달고도, 사용자에게는 깃털처럼 가벼운 경험을 선사해야 한다. 보안이 중요하다고 해서 스크롤이 버벅대거나 애니메이션이 뚝뚝 끊긴다면, 그건 실패한 아키텍처다.
핵심은 '메인 스레드 양보하기'다. 무거운 연산이나 위험한 코드 실행은 별도의 워커 스레드나 격리된 환경으로 미루고, 메인 스레드는 오직 화면을 그리고 사용자의 입력에 반응하는 데에만 집중해야 한다. 1초에 60번, 매끄럽게 화면을 그려내는 60fps의 약속은 타협할 수 없는 가치다.
비동기 통신을 효율적으로 설계하고, 불필요한 렌더링을 막으며, 메모리 누수를 차단하는 것. 보안이라는 무거운 갑옷을 입고도 발레리나처럼 우아하게 춤을 출 수 있어야 진정한 고수다. 사용자는 당신이 뒤에서 얼마나 치열하게 보안 전쟁을 치르고 있는지 알 필요가 없다. 그저 "와, 이 앱은 기능도 많은데 정말 빠르네"라고 느끼면 그만이다.
신뢰할 수 없는 것들을 위한 신뢰의 성
결국 플러그인 시스템을 설계한다는 건, 불신(Untrusted)을 관리하는 기술이다. 우리는 사용자가 만든 코드를 믿지 않는다. 외부 라이브러리도 믿지 않는다. 심지어 나 자신도 실수할 수 있음을 알기에 믿지 않는다. 이 철저한 불신을 바탕으로, 역설적이게도 가장 안전하고 자유로운 신뢰의 공간을 만들어내는 것이다.
아이프레임이라는 벽을 세우고, SES라는 수갑을 채우고, 라바모트라는 감시관을 두는 일. 이 모든 번거로움은 단 하나의 목표를 향한다. 누구나 자신의 아이디어를 펼칠 수 있는 자유, 그러면서도 누구도 다치지 않는 안전. 그 아슬아슬한 균형점 위에서 비로소 진정한 플랫폼이 탄생한다.
그러니 기억하라. 혁신은 언제나 위험한 가장자리(Edge)에서 피어난다. 그 가장자리를 안전한 울타리로 감싸 안는 것, 그것이 바로 아키텍처가 해야 할 일이다.
3줄 요약
- 사용자 코드를 실행하는 플러그인 시스템은 '아이프레임(격리)'과 'SES(속도)' 사이에서 줄타기해야 하는데, 둘을 합친 하이브리드 전략도 있다.
- 외부 라이브러리 공격까지 막으려면 '라바모트' 같은 도구로 공급망까지 꼼꼼하게 검문검색해야 한다.
- 보안 챙긴답시고 앱이 버벅대면 꽝이니, 무거운 작업은 뒤로 빼고 메인 스레드는 사용자 경험을 위해 쾌적하게 비워둬야 한다.
'MACHINE: EXPLOIT' 카테고리의 다른 글
| AI가 멍청한 건 프롬프트 탓이 아니다. 욕심 탓이다. (0) | 2025.11.27 |
|---|---|
| 그 낡은 '타르볼'이 여전히 섹시한 이유? 유닉스 철학의 우아한 생존법 (0) | 2025.11.26 |
| AI 조련의 정석: 알고리즘이 아니라 심리학으로 승부하라 (0) | 2025.11.25 |
| 당신의 삽질이 유독 처절하게 끝나는 이유? XY 문제 (0) | 2025.11.25 |
| 알고리즘의 노예에서 취향의 신민으로: 새로운 권력의 이동 (0) | 2025.11.24 |
| 외계인과 대화하는 유일한 방법: JSON-RPC라는 공용어에 관하여 (0) | 2025.11.23 |
| CEO는 없다, 코드만 있을 뿐: DAO라는 기묘한 유토피아 (0) | 2025.11.23 |
| 프롬프트 엔지니어링, 그 우아하고 치열한 탱고 (0) | 2025.11.23 |
| 버그 바운티는 심리전이다. 담당자를 홀리는 '보고서의 미학' (0) | 2025.11.21 |
| 인터넷에는 국경이 없지만, 검문소는 있다 (0) | 2025.11.21 |