id, title, category, status, verification_status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, created_at, updated_at, review_reason, merge_history, tags, raw_sources, applied_in, github_commit
id
title
category
status
verification_status
canonical_id
aliases
duplicate_of
source_trust_level
confidence_score
created_at
updated_at
review_reason
merge_history
tags
raw_sources
applied_in
github_commit
astra-path-boundary-guard-20260619
ASTRA 파일 경로 경계 가드 — validatePath prefix 약점 + brain:read 클램핑
Security
applied
validated
validatePath 경계
path traversal 방지
prefix 혼동 취약점
path.sep 경계
brain:read 클램핑
isWithinRoot
IPC 경로 가드
경로 탈출 차단
S
0.94
2026-06-19
2026-06-19
security
astra
path-traversal
ipc
electron
troubleshooting
E:/Wiki/astraai/src/security.ts
E:/Wiki/astraai/desktop/main.ts
E:/Wiki/astraai/src/agent/actions/fileCreateEdit.ts
E:/Wiki/astraai/tests/validatePath.test.ts
E:/Wiki/astraai @ branch (uncommitted, 2026-06-19)
🎯 한 줄 통찰 (One-line insight)
startsWith(root) 한 줄이 …/astraai를 …/astraai-secrets까지 통과시키던 경계 혼동을 path.sep 단위 비교로 막고, 두뇌 뷰어 IPC(brain:read)의 임의 파일 읽기를 두뇌 루트로 클램핑했다.
🧠 핵심 개념 (Core concepts)
prefix 혼동 (prefix confusion) : 구분자 가드 없는 startsWith는 /foo가 /foobar를 경계 안으로 오인한다 — 반드시 root + path.sep 또는 path.relative 기반 비교.
realpath 경계 검사 : 심볼릭 링크 우회를 막으려면 대상의 실제 경로 를 풀어 비교(isWithinRoot).
채널별 경계 : 두뇌 뷰어(brain:read)는 두뇌 루트로 제한 가능하나, 범용 파일 편집기(fs:read/write)는 의도적으로 전체 FS 접근 — 채널 목적에 맞는 경계를 둔다.
🩺 증상 (Symptom)
validatePath가 신뢰 루트 e:\wiki\astraai에 대해 e:\wiki\astraai-secrets\x 같은 형제 경로를 통과시켰다(접두 문자열 일치).
데스크톱 IPC astra:brain:read가 경로 검증 없이 임의 절대경로를 최대 200KB 읽어 반환.
🌐 환경 / 범위 (Environment & scope)
프로젝트: ASTRA (E:/Wiki/astraai). validatePath는 에이전트 파일 액션(create/edit/read/delete)의 샌드박스 근간.
데스크톱 IPC 핸들러(desktop/main.ts)는 렌더러가 호출하는 파일 채널.
🔁 재현 절차 (Reproduction)
작업폴더 C:\sandboxroot(부모가 드라이브 루트라 widening 없음)에서 validatePath(root, 'C:\\sandboxroot-evil\\x') 호출 → 기존엔 통과(BUG).
window.astra.brain.read('C:\\Windows\\win.ini') → 기존엔 임의 파일 내용 반환.
🔥 영향 및 심각도 (Impact & severity)
High. prefix 혼동은 샌드박스 형제 디렉토리 탈출을 허용. brain:read 무제한은 침해/주입된 렌더러가 임의 파일을 읽는 정보노출 경로.
🧠 근본 원인 (Root cause)
security.ts validatePath: trusted.some(root => normalizedTarget.startsWith(root)) — 구분자 가드 부재.
main.ts astra:brain:read: 경계 검사 없는 fs.readFileSync(filePath).
🔎 조사 과정 (Investigation)
보안 감사로 security.ts:52 prefix 비교 약점과 main.ts:321 무가드 읽기 식별.
렌더러 사용처 추적: brain:read는 Brain 뷰어가 brain:list 결과만 읽음 → 두뇌 루트 클램핑이 기능 손실 0.
반면 fs:read/write는 Explorer/FileEditor의 범용 편집기 (FileTree goParent 상위 탐색 + "연 파일이 진실의 원천"이라는 명시 주석)라 클램핑 시 문서화된 기능 파괴 → 제외 판단.
🛠️ 해결 (Resolution / applied fix)
validatePath 경계 비교를 path.sep 단위로 교정: normalizedTarget === r || normalizedTarget.startsWith(r + path.sep).
desktop/main.ts에 모듈 레벨 isWithinRoot(root, target)(realpath + sep 가드) 추가, astra:brain:read를 활성 두뇌 폴더로 클램핑.
💻 코드 패턴 (Code patterns)
✅ 검증 (Verification)
⚖️ 모순 및 업데이트 (Contradictions & updates)
의도적으로 클램핑하지 않은 것 : fs:read/fs:write(범용 편집기, FileTree goParent로 전체 FS 편집이 설계 의도이자 테스트됨), create_dir 절대경로(주석상 "저위험·비파괴 mkdir", 테스트 보장). 이들의 본질 위협(렌더러 침해)은 sandbox:true+navigation 가드가 올바른 완화책 — 별도 후속 과제.
즉 "모든 IPC를 workingDir로 묶는" 기계적 적용은 문서화된 기능을 깨므로 채널 목적별 경계 가 정답.
✅ 검증 상태 및 신뢰도
상태: applied (미커밋)
검증 단계: validated
출처 신뢰도: S
신뢰 점수: 0.94
중복 검사 결과: 신규 생성
🔗 지식 그래프 (Knowledge Graph)
📚 출처 (Sources)
[S1] E:/Wiki/astraai/src/security.ts — validatePath sep 경계 수정.
[S2] E:/Wiki/astraai/desktop/main.ts — isWithinRoot + astra:brain:read 클램핑.
[S3] E:/Wiki/astraai/src/agent/actions/fileCreateEdit.ts — create_dir 절대경로 의도(미변경 근거).
[S4] E:/Wiki/astraai/tests/validatePath.test.ts — 회귀 테스트.
📝 변경 이력 (Change history)
2026-06-19: 보안 감사에서 발견한 prefix 경계 약점 + 무가드 IPC 읽기 수정 후 최초 문서화(Claude Opus 4.8).