コンテンツにスキップ

QuickLeaks による自動マスク

端末の操作ログを共有する際、意図せず API キーやパスワード、個人情報が画面に映り込む危険が常に存在します。 console2svg ではこの情報漏洩を防ぐため、QuickLeaks と呼ばれる組み込みのシークレット検出エンジンを備えています。 シークレット検出を SVG 出力直前の文字列に対して実行し、検出された領域を端末のセル位置へ逆写像したうえで、SVG のソースコードそのものから秘密文字列を抹消します。

ルールセットの事前コンパイルと位置づけ

Section titled “ルールセットの事前コンパイルと位置づけ”

QuickLeaks は、シークレット検出ツールである Betterleaks の定義ルールと、console2svg 固有のルールを統合して事前生成された C# ソースコードです。 400 種類を超える検出ルールがあらかじめ .NET のネイティブコードとして組み込まれているため、実行時に外部プロセスを起動したり外部ルールファイルを読み込んだりする必要がありません。

ただし、QuickLeaks が担うのは「秘密情報と疑わしいパターンに一致した箇所の特定」までです。 外部のクラウドサービスへ通信して該当トークンが有効かどうかを検証するオンライン検証機能や、Git リポジトリ全体の履歴を遡るような重い解析は意図的に除外しています。 端末のキャプチャを待たせることなく、ミリ秒単位でマスキングを完了させるためです。

アンカー検索と専用ベリファイアによる高速化

Section titled “アンカー検索と専用ベリファイアによる高速化”

画面ごとに数百件の正規表現を毎回先頭から評価すると、特にアニメーション SVG や動画の生成時に深刻な処理遅延を招きます。 そこで QuickLeaks では、正規表現を保守的に静的解析し、一致時に必ず含まれる固定文字列(アンカー)を抽出しています。

実行時には、.NET の高速な文字列探索機能である SearchValues<string> を使って、画面テキスト全体からアンカーを一括検索します。 アンカーが見つかった箇所に限り、該当するルールのビットを立てて候補を絞り込みます。 さらに、GitHub のパーソナルアクセストークン(ghp_...)のような定形プレフィックスを持つトークンや、環境変数代入の典型パターンについては、正規表現エンジンを通さずに文字コードと長さを直接検証する 専用ベリファイア を実行します。

正規表現が必要なルールに対しても、AOT(事前コンパイル)対応の GeneratedRegex や、バックトラッキング(後戻り)を行わない RegexOptions.NonBacktracking を適用し、評価タイムアウトを設けることで、不正な入力による処理の停滞を完全に防止しています。

構造を残して値だけを隠すスコープ制御

Section titled “構造を残して値だけを隠すスコープ制御”

検出エンジンが一致を返した範囲の全体を、常にすべて塗りつぶすわけではありません。 出力の文脈を読者が理解できるよう、識別情報の一部を意図的に残す設計を採っています。

たとえば API_KEY=abcdef123456 という出力の場合、キー名である API_KEY= は残し、値の abcdef123456 だけをマスク対象にします。 認証情報を含む URI であれば、スキーム(https://)やホスト名はそのまま残し、ユーザー名とパスワードの部分だけを個別に隠します。 ホームディレクトリのパス表示でも、ベースディレクトリの構造は保持し、個人のユーザー名に該当するセグメントのみを絞り込んで覆います。

二段階マッピングによる座標の復元

Section titled “二段階マッピングによる座標の復元”

シークレット検出器が処理するのは単一のプレーンテキストですが、SVG 描画エンジンが必要とするのは「何行目の何列目から何列目までか」という端末セルの 2 次元座標です。 この変換を効率的に行うため、二段階マッピング を採用しています。

第 1 段階では、可視領域から行末の無駄な空白を除去し、自動折り返し行を連結した正規化文字列を 1 つだけ構築して QuickLeaks に渡します。 この段階で秘密情報が 1 件も検出されなければ、文字ごとの座標対応テーブルを作成する処理を丸ごとスキップします。

秘密情報が検出された場合に限り、第 2 段階として正規化文字列をもう一度走査し、各文字が画面上のどの行・列に対応するかを記録した座標マップを構築します。 大半の画面が秘密情報を含まない一般的なキャプチャにおいて、全文字分の座標オブジェクトを無条件にメモリ確保する無駄を避けるためです。

SVG ソースからの秘密文字列の物理的除去

Section titled “SVG ソースからの秘密文字列の物理的除去”

マスキング対象となったセルは、元の文字をそのまま残して上から不透明な図形を重ねるだけの処置を行いません。 SVG はテキスト形式のベクター画像であるため、単に上に図形を置いただけでは、ブラウザの「テキスト選択」やソースコードの表示から元のパスワードが容易に抜き取られてしまうためです。

console2svg では、該当セルの文字データそのものを * などの置換文字へ書き換えたうえで、その前面に視覚的なストライプ帯(マスクオーバーレイ)を描画します。 この置換処理を行ってもセルの文字幅や桁位置は不変に保たれるため、後続の文字レイアウトがずれる心配はありません。

アニメーション描画とマスクの干渉防止

Section titled “アニメーション描画とマスクの干渉防止”

前述のアニメーション最適化において、1 行の微小な変更を上書き描画する「行差分」という仕組みが存在します。 しかし、手動マスクパターン(--mask)が指定されている環境では、この行差分を意図的に無効化します。

マスク対象の秘密文字列が「差分の対象外となった変更前の部分」と「差分として上書きされる部分」の境界をまたいで存在していた場合、行を分割した状態では検出パターンに合致しなくなる恐れがあるためです。 描画サイズの圧縮よりも秘密情報の確実な隠蔽を最優先とし、安全側の動作を徹底しています。