Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
LavaDome — ShadowDOM을 활용한 안전한 DOM 트리 격리 및 캡슐화 | Kitploit
도구/GitHubGitHub/lavamoat/lavadome
Defensive ToolsWeb SecurityPrivacy
GitHublavamoat/lavadome

LavaDome

ShadowDOM을 활용한 안전한 DOM 트리 격리 및 캡슐화

저장소 보기웹사이트
365181년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

LavaDome 🌋️

~ DOM 노드 보안 Encapsulation을 위한 새로운 LavaMoat 도구 ~

⚠️ 실험적 [WIP] - 사용 시 위험은 본인이 감수하세요 (자세히 알아보기)

데모

LavaDome에 도전해 보세요 - 데모 앱을 방문하고, 콘솔을 열어, LavaDome 인스턴스 내부에서 비밀을 훔치기 위해 가능한 모든 것을 해보세요 (성공을 보고하세요)

미리보기 (클릭하여 펼치기)
LavaDome DEMO

동기

오늘날의 웹 표준에서는 DOM 하위 트리를 안전한 방식으로 선택적으로 격리하는 확립된 방법이 없습니다. 즉, 동일한 JavaScript 실행 환경을 공유하는 경우 일부 당사자에게는 액세스를 허용하면서 다른 당사자에게는 차단함으로써 DOM의 일부 섹션에 대한 액세스를 제어할 수 없습니다.

우리는 더 이상 우리 자신의 앱에 있는 코드를 신뢰할 수 없는 세상에 살고 있으며, 동일 출처 실행이 안전을 보장하지 않습니다. 프론트엔드에서 비밀을 보호하려면 동일 출처에서 실행되는 JavaScript 코드에 의해 손상될 수 없도록 하면서 사용자에게 콘텐츠를 제공할 수 있어야 합니다.

예시

이러한 기능의 한 사용 사례는 사용자 요청 시 개인 키를 평문으로 내보내는 MetaMask의 "개인 키 표시" 토글입니다. (클릭하여 펼치기)
Show private key feature by MetaMask

현재 이 민감한 콘텐츠는 일단 내보내지면 단순히 DOM에 첨부되어, 동일한 앱에서 실행되는 모든 주체가 완전히 액세스할 수 있게 됩니다. 즉, 개인 키에 액세스할 수 없어야 하는 코드 부분은 악성 코드가 DOM에 액세스할 수 있는 한 평문으로 쉽게 추출할 수 있습니다.

하지만 안심하세요. 우리는 이것이 해결 가능한 문제라고 믿습니다 👇

사용법

**LavaDome**은 현재 Vanilla JavaScript와 React를 지원합니다 (더 많은 지원 예정)

JavaScript```javascript

import { LavaDome as LavaDomeJavaScript } from '@lavamoat/lavadome-javascript';

const root = document.getElementById('root'); const lavadome = new LavaDomeJavaScript(root); lavadome.text(secret); lavadome.copy(); // copy to clipboard

### [React](https://github.com/lavamoat/lavadome/blob/main/packages/react)```javascript
import { LavaDome as LavaDomeReact, toLavaDomeToken } from '@lavamoat/lavadome-react';

function Secret({ text }) {
    const {token, copy} = toLavaDomeCapabilities(text);
    return <>
        <a onClick={copy}> copy to clipboard </a>
        <LavaDomeReact token={token} />
    </>;
}

API

루트 노드 외에도 모든 생성자는 선택적 옵션인 두 번째 인수를 허용합니다:```javascript // javascript new LavaDomeJavaScript(root, { // boolean unsafeOpenModeShadow: false, });

// react function Secret({ text }) { const {token} = toLavaDomeCapabilities(text); return <LavaDomeReact token={token} // boolean unsafeOpenModeShadow={false} /> }

### 안전한 사용

웹 코어의 한계로 인해 LavaDome을 안전하게 통합하려면 통합 개발자가 적극적으로 주의해야 할 몇 가지 사항이 있습니다:

#### 실행 순서

LavaDome은 다른 JavaScript 보안 소프트웨어와 마찬가지로 그보다 먼저 실행되는 코드에 항상 취약합니다.

즉, 절대적으로 신뢰하는 코드를 제외하고 LavaDome은 웹 애플리케이션 프로그램에서 가장 먼저 로드되는 코드여야 합니다.

이는 개발자가 즉시 사용해야 한다는 뜻은 아니지만(필요할 때만 사용하면 됨), 가능한 한 빨리 프로그램을 포함해야 합니다.

이를 올바르게(안전하게) 수행하려면 전체 프로그램에서 첫 번째 import/require 선언이어야 합니다:```javascript
import '@lavamoat/lavadome-react';
import 'other-stuff';

console.log('Program starts here');

그렇게 함으로써 LavaDome이 안전한 사용을 위해 스스로 준비할 수 있음을 보장합니다.

이는 @lavamoat/lavadome-react뿐만 아니라 나머지 LavaDome 패키지에도 동일하게 적용된다는 점에 유의하세요(따라서 여러 개를 가져올 필요가 없습니다).

자세한 내용은 보안(방어적 코딩)을 참조하세요.

CSP

사이드 채널링 공격과 웹 제약 때문에 원격 글꼴을 가져오는 방식이 LavaDome을 상대로 유효한 기법이 될 수 있습니다. CSS 영역에 포함되어 있기 때문에 현재 LavaDome으로 이 문제를 해결하는 것은 불가능합니다.

다행히도 이 문제는 CSP의 font-src 지시문을 사용해 효과적으로 해결할 수 있습니다.

이러한 공격을 완화하려면 웹 앱이 알 수 없는 서버에서 글꼴을 가져오는 것을 허용하지 않도록 하세요.

자세한 내용은 보안(사이드 채널링)을 참조하세요.

예측 불가능한 텍스트

개발자가 LavaDome에 제공하는 텍스트는 100% 예측 불가능해야 합니다. 그렇지 않으면 공격을 받아 유출될 수 있습니다.

따라서 앱이 "your key is 234789"를 표시해야 한다면 DOM 구조는 다음과 같아야 합니다.```html your key is 234789

그리고 다음과 같아서는 안 됩니다:```html
<span> <lavadome>your key is 234789</lavadome> </span>

자세히 알아보려면 보안(검색 가능성)로 이동하세요.

테스트

LavaDome를 테스트 환경에 통합하는 것은 까다로울 수 있습니다. LavaDome이 비밀을 숨기는 데 훌륭한 역할을 하기 때문에, 테스트에서도 그 비밀을 꽤 잘 숨기기 때문입니다!

LavaDome를 테스트 환경에 성공적으로 통합하려면 @lavamoat/lavadome-core에서 내보내는 LavaDomeDebug의 도움이 필요할 수 있습니다:```javascript // IMPORT/USE FOR TESTING/DEBUGGING PURPOSES ONLY - NEVER IN PRODUCTION! import { LavaDomeDebug } from '@lavamoat/lavadome-core';

다음은 `LavaDome` 기반 구성 요소를 테스트하는 데 도움이 되는 `LavaDomeDebug`가 내보내는 몇 가지 디버깅 유틸 메서드입니다:

#### `getTextByRoot()`

`LavaDome`이 연결된 루트(root)가 주어지면 `getTextByRoot()`는 내부 비밀(secret)을 재귀적으로 추출하여 재구성합니다. 이를 허용하려면 `LavaDome` 인스턴스가 원래 UNSAFE 옵션 `@unsafeOpenModeShadow`로 초기화되어 있어야 합니다. 이 옵션은 `LavaDome`의 내부 섀도우를 외부에서 접근 가능하게 만듭니다.

당연히 이는 UNSAFE하며 `LavaDome`을 완전히 취약하게 만들지만, 테스트/디버깅 목적으로만 사용하는 것이 타당합니다 - 프로덕션 환경에서는 이 옵션을 절대 활성화하지 않도록 하십시오!```javascript
new LavaDomeJavaScript(root, {
    unsafeOpenModeShadow: isThisTestingEnv, // boolean
}).text('123456');
LavaDomeDebug.getTextByRoot(root) === '123456'; // true

stripDistractionFromText()

웹 드라이버를 테스트에 사용하고 LavaDome 인스턴스 루트의 내부 텍스트를 추출하도록 지시하면, 비밀과 LavaDome의 디스트랙션 텍스트를 모두 포함하는 문자열이 반환됩니다.

디스트랙션 텍스트는 보안에 중요하지만 (보안(side-channeling) 참조), 웹 드라이버가 실제로 비밀의 일부가 아닌 문자를 추출하게 만듭니다.

이 문제를 해결하기 위해, 웹 드라이버로 얻은 텍스트가 주어지면 stripDistractionFromText()는 그 텍스트에서 디스트랙션 텍스트를 제거하여 테스트가 찾을 것으로 기대하는 정확한 문자열만 남깁니다.

디스트랙션 텍스트에 대해 걱정하지 마세요. 그 텍스트는 앱에서 사용자에게 절대 표시되거나 상호작용할 수 없지만, 보안상의 이유로 존재해야 합니다.```javascript new LavaDomeJavaScript(root).text('123456'); const element = await driver.findElement('#ROOT'); // driver const text = await element.getText(); // driver LavaDomeDebug.stripDistractionFromText(text) === '123456'; // true

## 개발

**`LavaDome`**의 로컬 개발 빌드를 설정하려면 이 저장소를 클론하고 다음 명령어 중 하나를 실행하세요:```bash
npm install && npm install --global serve

[No input content provided.]```bash yarn install && yarn global add serve

## 해결책

[`ShadowDom`](https://web.dev/articles/`ShadowDom`-v1) Web API는 DOM 노드를 격리하고 캡슐화할 수 있게 해줍니다. 비록 [보안 기능으로 설계된 것은 아니지만](https://web.dev/articles/`ShadowDom`-v1#:~:text=Note%3A%20Closed%20shadow%20roots%20are%20not%20very%20useful.%20Some%20developers%20will%20see%20closed%20mode%20as%20an%20artificial%20security%20feature.%20But%20let%27s%20be%20clear%2C%20it%27s%20not%20a%20security%20feature.for%20Closed%20mode%20simply%20prevents%20outside%20JS%20from%20drilling%20into%20an%20element%27s%20internal%20DOM.), `ShadowDom`은 페이지의 다른 곳에서 실행되는 JavaScript 및 CSS로부터 DOM 하위 트리를 격리하는 데 잘 작동합니다.

**`LavaDome`**의 기본 접근 방식은 `ShadowDom`을 활용하면서 [잠재적인 보안 허점](https://blog.ankursundara.com/shadow-dom/)을 신중하게 해결하는 것입니다.

**[LavaDome](https://github.com/lavamoat/lavadome/)**는 사용자 및 신뢰할 수 있는 코드와의 상호작용만 허용하면서 앱의 신뢰할 수 없는 JavaScript 및 CSS 코드의 접근 시도를 차단하는 프런트엔드 전용 구성 요소를 구현하기 위한 **LavaMoat 도구 모음의 보안 도구**입니다.

> [@arxenix](https://github.com/arxenix) 님의 `ShadowDom` 보안에 대한 [연구](https://blog.ankursundara.com/shadow-dom/)에 감사를 표합니다. 이 연구는 **`LavaDome`**에 구현된 주요 보안 개선 사항의 기반이 되었습니다.

## 목표

**`LavaDome`** 프로젝트는 다음 핵심 원칙을 따릅니다:

### 보안

우리의 최우선 과제는 빈틈없는 보안을 제공하는 것입니다. 우리는 민감한 정보를 표시할 때 안전하게 사용할 수 있도록 `ShadowDom` API를 고급 보안 속성으로 감쌌습니다.

이 노력에 대해 자세히 알아보려면 [보안](#Security)을 방문하세요.

### DX

우리는 간소화된 개발자 경험을 제공하기 위해 노력합니다. 이를 위해 다음을 수행할 것입니다:

1. 가능한 한 많은 인기 프레임워크(React, Angular 등)를 지원합니다;
2. API를 쉽고 간단하게 사용할 수 있게 만듭니다.

### 읽기 전용 모드

현재 단계에서는 쓰기 모드를 지원할 계획이 없습니다. 즉, **`LavaDome`**은 보호를 위해 일반 텍스트 콘텐츠만 허용하며, 그보다 복잡한 것은 허용하지 않습니다.

이는 쓰기 모드를 지원하려면 다루기 어려운 격리된 DOM을 구현해야 하기 때문이며, 이는 현재 시점에서 아직 감당할 준비가 되지 않은 여러 보안 문제를 야기합니다. 예를 들면:
도구 다운로드