メインコンテンツへスキップ

セキュリティと安全性

Champollion は、ロケールデータが信頼できないソースから来る可能性がある、細工されたファイル名がディレクトリの境界を越えようとする、そして LLM の出力が何でも含み得る、といった敵対的な環境でも安全に動作するよう設計されています。

脅威モデル

脅威攻撃ベクター対策
プロトタイプ汚染細工された JSON キー(__proto__constructorパース時に拒否
パストラバーサル../../etc/passwd のようなロケールコード設定されたディレクトリへのファイル書き込みを検証
コードブロックの破損LLM がコードフェンス内を翻訳するUnicode センチネルによるシールド
幻覚キーLLM が送信していないキーを返すレスポンス検証 — 受け入れられたキーのみ書き込み
トークン消費の暴走無限リトライループmaxRetries による予算上限

プロトタイプ汚染ガード

すべてのロケールキーは処理前にブロックリストに対して検証されます:

  • __proto__
  • constructor
  • prototype

これらのパターンに一致するキーはエラーとして拒否されます。これにより、攻撃者が細工されたロケールファイルを使って JavaScript オブジェクトのプロトタイプを変更することを防ぎます。

パスの封じ込め

ロケールファイルを書き込む際、champollion は出力パスが設定されたディレクトリ(localesDircontentDir)の範囲内に収まっているかを検証します。ロケールコードはサニタイズされるため、../../secrets のようなコードで期待されるディレクトリの外に書き込むことはできません。

ブロック保護

Markdown コンテンツの翻訳中、構造化された要素はテキストが LLM に送信される前に Unicode センチネルプレースホルダーに置き換えられます:

  1. コードブロック(フェンスおよびインライン) → センチネル
  2. Hugo ショートコード{{< >}}{{% %}}) → センチネル
  3. 生の HTML → センチネル
  4. 補間変数{{ .Count }}) → センチネル

翻訳後、センチネルは元のコンテンツに置き換えられます。LLM はコードブロック、ショートコード、HTML を一切見ないため、それらを破損させることができません。

レスポンス検証

LLM が JSON レスポンスを返す際、champollion は以下を検証します:

  • バッチで送信されたキーのみがレスポンスに含まれていること
  • 余分なキーが注入されていないこと
  • レスポンスが有効な JSON としてパースできること

幻覚キーは暗黙的に破棄されます。これにより、LLM の出力がロケールファイルに予期しない翻訳を注入することを防ぎます。

品質ゲート

すべての翻訳はディスクに書き込まれる前に、5 つの決定論的なチェックを通じて検証されます。詳細は 品質ゲート を参照してください。

指数バックオフ

API 呼び出しは、429(レート制限)および 5xx(サーバーエラー)レスポンスに対してジッター付きの指数バックオフを使用します。遅延を増加させながら 3 回リトライすることで、障害発生中に 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.

1 つのファイルの失敗が同期全体を止めることはありません — エラーはログに記録され、パイプラインは次のファイルへと処理を続けるため、1 回の実行で最大限の進捗が得られます。

同期後の検証

すべての翻訳が完了した後、champollion はディスクから書き込まれたロケールファイルを再読み込みし、検証パスを実行します。これにより、同期が成功を報告しても実際には翻訳が誤っているというギャップを検出します:

  • キーの一致 — すべてのソースキーが各ターゲットに存在すること
  • [EN] マーカー — 以前の実行からのレガシーフォールバックマーカー
  • 空の翻訳 — すり抜けた空白の値
  • スクリプト準拠 — ASCII のみの翻訳になっている非ラテン文字ロケール
  • プレースホルダーの保持 — ICU プレースホルダーがソースと一致すること

--no-verify でスキップするか、npx champollion verify でスタンドアロン実行できます。

テスト

セキュリティ特性は敵対的テストスイートによって検証されます:

npm run test:redteam # prototype pollution, path traversal, encoding attacks

関連情報