レッスン 6

よくある Base64 のミス

アルファベットの取り違え、改行、UTF-8 テキストの誤デコード。

Base64 の落とし穴は 4 テーマに集約されます: アルファベット不一致空白の驚き二重エンコードUTF-8 テキスト vs 生バイトの誤処理。

アルファベットの混乱

症状:

  • -/_(URL-safe)と +//(標準)が混在すると断続的デコード失敗
  • 仕様が Base64URL を期待する場所に +/ が残る JWT 風断片

対処: 変換を集中化; 正規サンプル(パディング付き MIME、パディングなし URL-safe ベクトル)のラウンドトリップをユニットテスト。

サービス全体に regex「修正」を散らさない — いずれかのパスが trim 忘れや誤正規化をします。

大文字小文字の癖

アルファベットの A–Z vs a–z セグメントインデックスは大文字小文字が重要; payload 全体に誤って .toLowerCase() すると情報が破壊されます。

残存空白と改行

PDF/メールからのコピーは stray スペースとソフト改行を注入しがち。

戦略:

  • 仕様が許すときだけ ignoreWhitespace フラグでデコード
  • PEM パースは header/footer 行を除去 — 内部の任意空白は信頼できない
  • ログパイプラインがレコード分割 — 疑わしく短い断片を拒否

不可視 Unicode 空白(narrow no-break space、BOM)はバグとして扱い、明示許可リストで早期正規化。

URL デコード順序バグ

percent デコードを二重適用したり Base64 正規化と順序を入れ替えるとゴミバイト — 特に %2B%2F%3D+/= 相当)。

演習: 複数プロキシを通るユーザー提出トークン — フレームワークがスペースを書き換える前の生クエリを捕捉。

意図しない二重エンコード

誰かが資格情報 JSON を Base64 エンコード、文字列を受け取り、誤って再び Base64 — DB に保存された成果物はどの当事者の想定とも合わない。

コードで命名(encodeOnce、層責任を明確化)し、アサーションログは秘密を漏らさず長さ + 先頭数文字のハッシュを出力してフォレンジック diff に。

UTF-8 テキストの混乱

「中国語文字列を Base64 したらおかしい」 — よくある失敗は層の取り違え: UTF-8 バイトをエンコードしたのに別 charset でデコード、または同一論理テキストの別正規化と比較。

言語のヘルパーでパイプラインを明示: Unicode 文字列 → UTF-8 バイト → Base64 テキスト、デコード時は逆。

レガシー単バイトデフォルトを仮定しない — プラットフォームコードページはデコード後に文字化けを生みがち。

JSON payload

JSON は UTF-8(または文書化されたエスケープ重視の代替)を要求。サーバー正規化 vs BOM 付き pretty-print 差分ではなく、シリアライズ済み JSON バイトをエンコード。

DB の text vs binary 列

Base64 デコード protobuf を TEXT 型列に照合順序変換で保存すると微妙に破損 — 不適切だが ORM 型誤ラベルで観察されます。

セキュリティ脚注

Base64 blob は素人目には不透明だが機密ではない。Base64 だけで秘密を運ぶのは信頼できない輸送上の平文と同等。

署名と MAC は正規バイトレイアウトで動作 — パディング形式や大文字小文字を変えると静かに検証失敗。

定数時間の落とし穴

稀だが現実: Base64 由来秘密の素朴な文字列等価比較 vs タイミング攻撃 — 生トークン扱いでは crypto ライブラリの安全 compare を優先 — Base64 固有ではないが隣接。

要点

相互運用はチームが次に合意するとき勝ちます。

  1. アルファベットとパディングルール
  2. デコード前正規化(改行/URL ステップ)
  3. 内容がテキスト(UTF-8)か不透明バイトか
  4. 文書化プロトコル層なしの再帰エンコード禁止

CI にゴールデンベクトルを置き早期に回帰を捕捉。

実践したいときは関連する DevCove ツールを使えます。任意であり、このレッスンの必須部分ではありません。

関連ツールを開く

コース概要へ戻る