보안 및 안전
Champollion은 적대적인 환경 — 로케일 데이터가 신뢰할 수 없는 출처에서 올 수 있고, 조작된 파일 이름이 디렉터리 경계를 벗어날 수 있으며, LLM 출력에 무엇이든 담길 수 있는 환경 — 에서 안전하도록 설계되었어요.
위협 모델
| 위협 | 공격 벡터 | 완화 방안 |
|---|---|---|
| 프로토타입 오염 | 조작된 JSON 키 (__proto__, constructor) | 파싱 시점에 거부됨 |
| 경로 탐색 | ../../etc/passwd 같은 로케일 코드 | 파일 쓰기를 구성된 디렉터리로 검증함 |
| 코드 블록 손상 | LLM이 코드 펜스 안을 번역함 | 유니코드 센티넬 차폐 |
| 환각 키 | LLM이 전송되지 않은 키를 반환함 | 응답 검증 — 수락된 키만 기록됨 |
| 과도한 토큰 소비 | 무한 재시도 루프 | maxRetries을 통해 예산 상한 적용 |
프로토타입 오염 방지
모든 로케일 키는 처리 전에 차단 목록과 대조하여 검증돼요:
__proto__constructorprototype
이러한 패턴과 일치하는 키는 오류와 함께 거부돼요. 이는 공격자가 조작된 로케일 파일을 사용해 JavaScript 객체 프로토타입을 변경하는 것을 방지해요.
경로 격리
로케일 파일을 작성할 때 champollion은 출력 경로가 구성된 디렉터리(localesDir, contentDir) 내에 머무는지 검증해요. 로케일 코드는 정제되며 — ../../secrets 같은 코드는 예상 디렉터리 밖에 쓸 수 없어요.
블록 보호
Markdown 콘텐츠 번역 중에는 구조화된 요소들이 텍스트가 LLM에 전송되기 전에 유니코드 센티넬 플레이스홀더로 대체돼요:
- 코드 블록(펜스 및 인라인) → 센티넬
- Hugo 숏코드(
{{< >}},{{% %}}) → 센티넬 - 원시 HTML → 센티넬
- 보간 변수(
{{ .Count }}) → 센티넬
번역 후 센티넬은 원본 콘텐츠로 대체돼요. LLM은 코드 블록, 숏코드, HTML을 절대 보지 못하므로 — 손상시킬 수 없어요.
응답 검증
LLM이 JSON 응답을 반환할 때 champollion은 다음을 검증해요:
- 배치에서 전송된 키만 응답에 나타나는지
- 추가 키가 주입되지 않았는지
- 응답이 유효한 JSON으로 파싱되는지
환각 키는 조용히 폐기돼요. 이는 LLM 출력이 예기치 않은 번역을 로케일 파일에 주입하는 것을 방지해요.
품질 게이트
모든 번역은 디스크에 기록되기 전에 다섯 가지 결정론적 검사를 거쳐 검증돼요. 자세한 내용은 품질 게이트를 참고하세요.
지수 백오프
API 호출은 429(속도 제한) 및 5xx(서버 오류) 응답에 대해 지터가 적용된 지수 백오프를 사용해요. 지연 시간이 증가하는 세 번의 재시도는 장애 시 API에 과부하를 주는 것을 방지해요.
요청 타임아웃
모든 API 요청은 AbortController을 통해 30초 타임아웃을 가져요. 이는 죽은 연결에서 동기화 프로세스가 무한정 멈추는 것을 방지해요.
명시적 번역 실패
API를 사용할 수 없거나 번역이 실패할 때 champollion은 조용히 쓰레기 값을 기록하는 대신 실행 가능한 안내와 함께 명시적인 오류를 발생시켜요. 동기화 중에 [EN] 접두사가 붙은 플레이스홀더는 절대 기록되지 않아요.
[ERR] Content sync for fr: no API key available.
Set OPENROUTER_API_KEY in .env.local to translate content.
한 파일의 실패가 전체 동기화를 멈추지는 않아요 — 오류가 기록되고 파이프라인은 다음 파일로 계속 진행되므로, 실행마다 최대한의 진행률을 얻을 수 있어요.
동기화 후 검증
모든 번역이 완료된 후 champollion은 기록된 로케일 파일을 디스크에서 다시 읽고 검증 패스를 실행해요. 이는 동기화가 성공으로 보고하는 것과 실제로 번역이 잘못된 것 사이의 간극을 포착해요:
- 키 일치 — 모든 소스 키가 각 대상에 존재함
[EN]마커 — 이전 실행에서 남은 레거시 폴백 마커- 빈 번역 — 빠져나간 빈 값
- 스크립트 준수 — ASCII 전용 번역이 있는 비라틴 로케일
- 플레이스홀더 보존 — ICU 플레이스홀더가 소스와 일치함
--no-verify으로 건너뛰거나 npx champollion verify로 단독 실행하세요.
테스트
보안 속성은 적대적 테스트 스위트로 검증돼요:
npm run test:redteam # prototype pollution, path traversal, encoding attacks
참고
- 아키텍처 — 세 부분으로 구성된 생태계가 어떻게 연결되는지
- CLI 레퍼런스 — integrity — 무결성 검사 명령
- CLI 레퍼런스 — provenance — 출처 감사 명령
- 플러그인 명세 — 플러그인 매니페스트의 출처 필드
- 품질 게이트 — 번역 수준의 안전 검사