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

セキュリティと安全性

Rosettaは、敵対的な環境でも安全に動作するように設計されています。このような環境では、ロケールデータが信頼できないソースから提供されたり、細工されたファイル名がディレクトリの境界を越えたり、LLMの出力に予期せぬ内容が含まれたりする可能性があります。

脅威モデル

脅威攻撃ベクター緩和策
プロトタイプ汚染細工されたJSONキー (__proto__, constructor)パース時に拒否
パストラバーサル../../etc/passwd のようなロケールコード設定されたディレクトリへのファイル書き込みを検証
コードブロックの破損LLMがコードフェンス内を翻訳するUnicodeセンチネルによる保護
ハルシネーションによるキーLLMが送信されていないキーを返すレスポンスの検証 — 許可されたキーのみを書き込み
トークンの過剰消費無限リトライループmaxRetries による予算上限の設定

プロトタイプ汚染ガード

すべてのロケールキーは、処理される前にブロックリストと照合して検証されます。

  • __proto__
  • constructor
  • prototype

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

パスの封じ込め

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

ブロック保護

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

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

翻訳後、センチネルは元のコンテンツに置き換えられます。LLMがコードブロック、ショートコード、HTMLを認識することは決してないため、これらが破損することはありません。

レスポンスの検証

LLMがJSONレスポンスを返した際、rosettaは以下の点を検証します。

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

ハルシネーションによって生成されたキーは暗黙的に破棄されます。これにより、LLMの出力がロケールファイルに予期せぬ翻訳を注入するのを防ぎます。

品質ゲート

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

エクスポネンシャル・バックオフ

API呼び出しでは、429 (レート制限) および 5xx (サーバーエラー) のレスポンスに対して、ジッターを伴うエクスポネンシャル・バックオフを使用します。遅延を増やしながら3回リトライすることで、障害発生時にAPIへ過剰な負荷をかけるのを防ぎます。

リクエストのタイムアウト

すべてのAPIリクエストには、AbortController を介して30秒のタイムアウトが設定されています。これにより、切断された接続によって同期プロセスが無限にハングするのを防ぎます。

翻訳失敗時のフェイルラウド

APIが利用できない場合や翻訳が失敗した場合、rosettaは無意味なデータを暗黙的に書き込むのではなく、実行可能なガイダンスを伴う明確なエラーをスローします。同期中に [EN] プレフィックスが付いたプレースホルダーが書き込まれることは決してありません。

[ERR] Content sync for fr: no API key available.
Set OPENROUTER_API_KEY in .env.local to translate content.

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

同期後の検証

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

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

--no-verify でスキップするか、npx i18n-rosetta verify を使用して単独で実行できます。

テスト

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

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

関連項目