fix(bridge): CSP script-src 'unsafe-inline' patch for renderer v3 execution #task-264

This commit is contained in:
2026-03-09 20:35:38 +09:00
parent da31740cc2
commit 08077e8afa
6 changed files with 72 additions and 1 deletions

View File

@@ -241,4 +241,11 @@
- AG 패치 후 **반드시 풀 프로세스 재시작** 필요 (Reload Window 불충분) - AG 패치 후 **반드시 풀 프로세스 재시작** 필요 (Reload Window 불충분)
- **양쪽 HTML (workbench.html + workbench-jetski-agent.html) 모두 inline 패치** 필수 - **양쪽 HTML (workbench.html + workbench-jetski-agent.html) 모두 inline 패치** 필수
- HTML 패치 변경 시 **`%APPDATA%\Antigravity\CachedData` 삭제 필수** (V8 바이트코드 캐시 무효화) - HTML 패치 변경 시 **`%APPDATA%\Antigravity\CachedData` 삭제 필수** (V8 바이트코드 캐시 무효화)
- **CSP `script-src``'unsafe-inline'` 패치 필수** (없으면 인라인 스크립트 무조건 차단)
### [2026-03-09] CSP script-src — 인라인 스크립트 무조건 차단
- **증상**: HTML 패치 ✅, 체크섬 ✅, CachedData 삭제 ✅ — 그런데도 renderer v3 스크립트 미실행 (`/deep-inspect` timeout)
- **원인**: `workbench.html`의 CSP `<meta http-equiv="Content-Security-Policy">`에서 `script-src 'self' 'unsafe-eval' blob:`**`'unsafe-inline'` 없음**. 브라우저가 인라인 `<script>` 태그를 무조건 차단
- **해결**: CSP의 `script-src``'unsafe-inline'` 추가. Extension `setupApprovalObserver()`에 CSP 자동 패치 로직 영구 추가
- **주의**: `style-src`에는 `'unsafe-inline'`이 있어 스타일은 동작 → 스크립트만 차단되는 것이 함정. `connect-src``http://127.0.0.1:*` 존재하여 HTTP fetch는 허용됨 (CSP 통과 시 통신은 문제없음). 이 CSP 이슈는 **V8 CachedData 이슈와 동시에 존재**하여 진단이 매우 어려웠음

View File

@@ -8,3 +8,4 @@
| 004 | 18:08~18:23 | Deep inspect HTTP endpoint (/deep-inspect) + 렌더러 재귀 인스펙터 | `a07d9d3` | 🔧 | | 004 | 18:08~18:23 | Deep inspect HTTP endpoint (/deep-inspect) + 렌더러 재귀 인스펙터 | `a07d9d3` | 🔧 |
| 005 | 18:30~19:28 | workbench.html inline v3 패치 누락 수정 + pre-patch 검증 | `b61cff1` | 🔧 | | 005 | 18:30~19:28 | workbench.html inline v3 패치 누락 수정 + pre-patch 검증 | `b61cff1` | 🔧 |
| 006 | 19:38~19:56 | V8 CachedData 진단 + 캐시 삭제 (renderer 미실행 근본 원인) | docs only | 🔧 | | 006 | 19:38~19:56 | V8 CachedData 진단 + 캐시 삭제 (renderer 미실행 근본 원인) | docs only | 🔧 |
| 007 | 20:04~20:28 | CSP script-src `'unsafe-inline'` 패치 (renderer 미실행 진짜 근본 원인) | TBD | 🔧 |

View File

@@ -0,0 +1,45 @@
# CSP script-src `'unsafe-inline'` 패치 — 렌더러 v3 스크립트 미실행 근본 원인
- **시작**: 2026-03-09 20:04 KST
- **종료**: 2026-03-09 20:28 KST
- **상태**: 🔧 미완료 (AG 재시작 후 /deep-inspect 검증 필요)
- **Vikunja**: #264 → 진행중
## 핵심 발견
### Root cause: CSP `script-src`에 `'unsafe-inline'` 없음
이전 세션(#005~#006)에서 HTML 패치 + 체크섬 + CachedData 삭제 모두 정상이었으나 renderer v3 스크립트가 미실행되는 근본 원인 발견.
**CSP 분석:**
```
script-src 'self' 'unsafe-eval' blob: ← 'unsafe-inline' 없음!
style-src 'self' 'unsafe-inline' ← 스타일은 허용 (함정)
```
- `<script src="./x.js">``'self'`로 허용되나 `vscode-file://`가 커스텀 파일 서빙 차단
- `<script>inline code</script>``'unsafe-inline'` 없어 CSP가 무조건 차단
- **두 방법 모두 차단 → deadlock이었음**
### 추가 검증
- `require-trusted-types-for 'script'` → static `<script>` 태그에 영향 없음 (확인)
- 스크립트 내 `innerHTML`/`document.write`/`eval` → 0건 (Trusted Types 충돌 없음)
- `connect-src``http://127.0.0.1:*` → Bridge HTTP 통신은 CSP 허용 범위
### 이전 세션 KI와의 관계
- KI `renderer_security_and_lifecycle.md` Line 28: "인라인 스크립트로 우회" → 해결책으로 기록
- **그러나 인라인도 CSP가 차단한다는 분석이 누락** → 이번에 최초 발견
## 수정 내역
| 파일 | 변경 |
|------|------|
| `extension/src/extension.ts` | `setupApprovalObserver()`에 CSP `'unsafe-inline'` 자동 패치 로직 추가 |
| `.agents/references/known-issues.md` | CSP script-src 이슈 + 핵심 전제에 CSP 패치 필수 추가 |
| 양쪽 HTML (수동) | `'unsafe-inline'` 추가 + 체크섬 업데이트 + CachedData 삭제 |
## 다음 단계 (다음 세션)
1. AG 완전 재시작
2. `curl.exe http://127.0.0.1:34332/deep-inspect` → 렌더러 응답 확인
3. 응답 시 webview iframe 접근성 분석 → E2E 승인 테스트

View File

@@ -303,6 +303,13 @@ async function setupApprovalObserver() {
continue; continue;
} }
let html = fs.readFileSync(htmlPath, 'utf8'); let html = fs.readFileSync(htmlPath, 'utf8');
// CRITICAL: Patch CSP to allow inline scripts.
// Default CSP has script-src 'self' 'unsafe-eval' blob: — NO 'unsafe-inline'.
// Without 'unsafe-inline', all inline <script> tags are silently blocked.
if (html.includes('script-src') && !html.match(/script-src[^;]*'unsafe-inline'/)) {
html = html.replace(/(script-src\s[^;]*?)('self')/, "$1$2\n\t\t\t\t\t'unsafe-inline'");
logToFile(`[OBSERVER] ${htmlFileName} CSP patched: added 'unsafe-inline' to script-src`);
}
// Remove old external script tag if present (legacy, cannot be served) // Remove old external script tag if present (legacy, cannot be served)
const extMarkerStart = '<!-- AG SDK [variet-gravity-bridge] -->'; const extMarkerStart = '<!-- AG SDK [variet-gravity-bridge] -->';
const extMarkerEnd = '<!-- /AG SDK [variet-gravity-bridge] -->'; const extMarkerEnd = '<!-- /AG SDK [variet-gravity-bridge] -->';

File diff suppressed because one or more lines are too long

View File

@@ -265,6 +265,17 @@ async function setupApprovalObserver() {
} }
let html = fs.readFileSync(htmlPath, 'utf8'); let html = fs.readFileSync(htmlPath, 'utf8');
// CRITICAL: Patch CSP to allow inline scripts.
// Default CSP has script-src 'self' 'unsafe-eval' blob: — NO 'unsafe-inline'.
// Without 'unsafe-inline', all inline <script> tags are silently blocked.
if (html.includes('script-src') && !html.match(/script-src[^;]*'unsafe-inline'/)) {
html = html.replace(
/(script-src\s[^;]*?)('self')/,
"$1$2\n\t\t\t\t\t'unsafe-inline'"
);
logToFile(`[OBSERVER] ${htmlFileName} CSP patched: added 'unsafe-inline' to script-src`);
}
// Remove old external script tag if present (legacy, cannot be served) // Remove old external script tag if present (legacy, cannot be served)
const extMarkerStart = '<!-- AG SDK [variet-gravity-bridge] -->'; const extMarkerStart = '<!-- AG SDK [variet-gravity-bridge] -->';
const extMarkerEnd = '<!-- /AG SDK [variet-gravity-bridge] -->'; const extMarkerEnd = '<!-- /AG SDK [variet-gravity-bridge] -->';