-
Notifications
You must be signed in to change notification settings - Fork 0
Security Model ko
English | 中文 | 日本語 | 한국어 | Español | Português | Русский
browsa는 임의의 웹 콘텐츠를 모델에게 먹이고, 모델 출력을 확장 페이지 안에 렌더하고, 사용자 대신 쿠키 실린 요청을 CDN에 보낸다 — 보안 경계는 모두 그 세 체인 위에 놓인다. 원칙: "원본 아티팩트를 보존"하는 쪽으로 fail open한다, 잘못된 데이터를 조용히 만들어내는 일은 결코 없다.
- 확장 페이지 CSP:
script-src 'self' 'wasm-unsafe-eval'—new Function/eval 없음; WASM 인스턴스화는 허용. - Mol*/RDKit embind 접착제는 eval로 클래스 팩토리를 만든다 → build.mjs가 복사 시점에 벤더를 패치한다(손작성 인보커; 즉실행 init은 지연화). 패치 정규식은 안정적인 문자열에 고정되고 molstar 업그레이드가 매칭을 멈추면 빌드를 THROW한다.
-
검증 환경 교훈: dev-preview는 기본 CSP가 eval을 허용하는 평범한 http 페이지다 — CSP 위반을 잡을 수 없다. 벤더 교체 후에는 실제 확장 안에서 실행하라(
launchPersistentContext --load-extension, xvfb) canvas/svg가 존재하고 CSP/EvalError 콘솔 출력이 0임을 단언하라.
-
ALLOWED_URI_REGEXP를sanitize()옵션으로 넘기지 마라 — DOMPurify는 그것을 자체 안전 목록에 없는 모든 허용 속성의 "값"에 적용해<ol start="N">의 맨 숫자를 떼어낸다(실제 버그: 리스트 번호 붕괴). URI 검사는 명시적URI_ATTRS집합으로 스콥된uponSanitizeAttribute훅을 통과한다. - DOMPurify의 data: 허용목록은
data:image/svg+xml(스크립트를 품을 수 있다)을 덮지 않는다 — 모듈 로드 때 한 번 등록되는 훅이 이것을 막는다. - mermaid는
securityLevel:'loose'(노드 라벨 안 KaTeX)가 필요하므로, 그 SVG는 반드시 벤더sanitizeMermaidSvg(살균 + 퇴화 렌더 거절)를 통과해야 한다 — load-bearing 보안이다.
-
<all_urls>host_permissions: 확장 컨텍스트 페치는 CORS 면제다(Ark / AlphaFold / RCSB / raw.githubusercontent가 이것에 의존), DNR이 CDN 요청 헤더를 주입하고, 스크립트가 어떤 탭에도 주입된다. 백엔드 프록시가 없으므로 이것은 필요다. -
activeTab제거됨(사이드 패널에서는 절대 동작하지 않는다; 주입은 명시적 tabId를 통과한다). -
unlimitedStorage: 키프레임/페이지 이미지 데이터 URL은 히스토리에 산다(첫 요청 측 압축까지) — 기본 10MB 쿼터에 실제로 한 번 도달한 적이 있다. - 확장 개인 키 백업은 저장소 밖에 산다(
/root/workspace/browsa-keys/, 절대 커밋되지 않음).
ASR 다운로드는 CDN이 받아주는 Referer/Origin/쿠키가 필요하다. 세션-스콥 DNR 규칙은 CDN 도메인(bilivideo / googlevideo) + initiatorDomains: [이 확장의 ID]로 필터하고, chrome-extension Origin을 사이트 자신의 것으로 재작성한다. 두 플랫폼 모두 필요하다("YouTube는 헤더가 필요 없다, POT가 URL에 있다"는 가정은 틀렸다 — 라이브 테스트에서 모든 새 스트림이 403했다).
페이지는 LLM 독자를 겨냥한 지시를 숨길 수 있다. 세 층:
-
<template>요소와 HTML 주석은 Readability가 파스하기 전에 제거된다; - CSS 숨김 요소(display/visibility/opacity/font-size:0/제로 크기 박스)는 LIVE 문서에서 표시되고, 클론에서 제거된 뒤, 표시가 해제된다(페이지는 결코 변형된 채 남지 않는다); 비지 않은 textContent를 가진 요소만 검사된다(비용 상한);
- 출력 텍스트는 제로폭 문자, 제어 문자, 짝이 없는 UTF-16 서러게이트를 떼어낸다(짝 인식 정규식 — 무차별 제거는 정당한 이모지를 죽인다).
chrome.scripting.executeScript는 정확히 하나의 함수를 직렬화한다 — 헬퍼는 주입되는 함수 안에 중첩되어야 한다(ADR-0009; countImages는 모듈 수준 형제였고 실제 Chrome에서 ReferenceError를 던졌는데, 본문을 이어붙인 테스트는 아무것도 보지 못했다).
- 쿠키 동의 클릭: 컨테이너 게이트 + 위험 단어 거부권(구매/삭제/지불/비우기/초기화 … 두 언어 모두).
- 더보기 확장: 내비게이션 가능한
<a href>는 절대 클릭하지 않는다(실제 사건: 브랜드 링크가 첨부 도중 탭을 내비게이션했다); 크롬 영역 제외(nav/aside/[role=…], GitHub 메가메뉴와 labuladong 사건 후 강화); 클릭으로 열린 대화상자는 취소 라벨 컨트롤로 닫고 그 패스를 멈춘다. - lazyload용 스크롤은 SIGNAL 게이트다(lazy/가상화 신호가 존재할 때만); 페인트 억제는
<html>에opacity:0을 쓴다(절대visibility가 아니다 — 페이지 자체의 리빌 안무가 끼일 수 있다); scrollY는 언제나 복원된다. - GitHub
/blob/URL은 페이지 자동화를 전부 우회하는 raw 빠른 경로를 탄다(열린 메뉴가 클론 DOM을 오염 — 실제 사건).
| 설치 형태 | 확장 ID |
|---|---|
| Chrome Web Store |
kghjmmajnpbkljankbbjbmnhfdocaeho (CWS 고정) |
| 저장소 디렉터리 로드(manifest가 key 소지) |
apoodheofdhglelbnmggeokbhampbmgn (key에서 유도) |
| 릴리즈 zip 풀기 | 경로 유도, 기계마다 다름 (패키징이 key를 떼어낸다) |
chrome://extensions에 보이는 ID가 유일한 지상 진실이다. 로컬 게이트웨이는 ws://를 쓴다(wss는 거절); 게이트웨이 설정은 시작 때 한 번 읽는다.
원본 출처: AGENTS.md sanitizer-gotchas, preExtractCleanup, DNR, extension-ID 절; ADR-0008 / 0009. 권위판: Security-Model(영어) / Security-Model-zh(중국어) — AI 초벌 번역 스냅숏, 동기화 2026-10-01.
English
- Home
- Architecture
- Rendering Pipeline
- Storage Model
- Providers and Agents
- ASR and Video Analysis
- Security Model
- Design Decisions
- Contributing
中文
相关 / Related
日本語
한국어
Español
- Inicio
- Arquitectura
- Pipeline de renderizado
- Modelo de almacenamiento
- Proveedores y agentes
- ASR y análisis de vídeo
- Modelo de seguridad
- Decisiones de diseño
- Contribuir
Português
- Início
- Arquitetura
- Pipeline de renderização
- Modelo de armazenamento
- Provedores e agentes
- ASR e análise de vídeo
- Modelo de segurança
- Decisões de design
- Contribuindo
Русский