# ログに秘密のトークンが平文で残っていた：呼び忘れようがない唯一の出口で伏せる

> 通信の部品のエラーメッセージに URL がそのまま入り、取得サービスのトークンがログに出ていた。前に作った伏字の関数は、明示的に呼ぶ場所にしか効かず、呼び元は 50 か所以上。ログの唯一の出口で伏せる形に直した。

- URL: https://koshinstudio.com/notes/secret-in-logs/
- 公開: 2026-10-17
- 書いた人: Koshin（https://koshinstudio.com/about/）
- サイト: Koshin Studio

  English version (https://koshinstudio.com/en/notes/secret-in-logs/)

トレカダッシュ 開発の記録 ／ 2026年8月

  iOS アプリ「トレカダッシュ (https://koshinstudio.com/works/torecadash/)」の裏側のログを調べていて、外部サービスの秘密の値（API のトークン）が、そのまま書かれているのを見つけました。2026 年 8 月 24 日のことです。

  宿題として「期限なし、任意」に置いていた件でした。サーバーの実際のログを確認すると、実際に漏れていました。この記事は、原因と、「呼び忘れようがない出口で、伏字にする」直し方の記録です。

  この記事は、2026 年 8 月 24 日の作業の記録から書いています。本物の値は、書いていません。

## ログに、本物のトークンが出ていた

  サーバーのログに、こういう行がありました（トークンの部分は、本物でした）。

  WARN [再検証] 取得サービス経由での取得に失敗 [https://…]:
request to https://api.scrape.do/?token=＜本物のトークン＞&url=… failed, reason: read ETIMEDOUT
  原因は、通信の部品（node-fetch）のエラーメッセージに、リクエストの URL が、そのまま入ることでした。URL の中のtoken=の部分に、秘密の値が含まれています。

## 前にも、同じことをして、直したつもりだった

  2026 年 8 月 19 日にも、楽天の API の認証情報で、同じことが起きていました。そのとき、ログの文字列から秘密の値を伏せる関数（redactSecretsForLog）を作りました。ところが、この関数は、明示的に呼んだ場所にしか、効きません。取得サービスを呼ぶ場所は、50 か所以上あり、呼び忘れていたのです。

## 直し方：すべてのログが通る、唯一の出口で、伏せる

  同じ直し方を繰り返さないよう、2 段構えにしました。

- ログの出口（fmt()）で伏せる。サーバーの全部のログが、必ず通る、唯一の出口です。ここで伏せれば、呼び忘れようがありません。URL の中の、token、api_key、secret、applicationId、accessKey、affiliateId、setCookies などと、X の監視のログイン用クッキーの生の書き方の、両方を伏せます。

- 取得サービスを呼ぶ関数で、エラーを作り直す。呼び出し元に返す前に、伏せた文字列で、エラーを作り直します。関数が、データの変化で動く側（Cloud Functions のトリガー）でも使われるので、そちらのログにも効かせるためです。

  実際のログの文字列 4 種で、伏せられることを確かめました。通常のログの行は、変化しないことも確かめました（deadline=2026-08-30 のような、無関係な = を、伏せてしまっては困ります）。

## すでに出てしまったログは、どうするか

  直しても、すでに出てしまったログには、本物のトークンが残っています。サーバーの管理者の権限でしか読めないので、緊急性は低いのですが、気になる場合は、サービスの管理画面でトークンを再発行して、サーバーの設定の値を差し替えます。この記録の時点では、これは、判断待ちの項目にしていました。

## 分かったこと

> 呼び忘れる場所が 50 あるなら、呼び忘れようがない場所で、1 度だけ行う。

- 明示的に呼ぶ対策は、呼び忘れで漏れる。50 か所のうち 1 か所でも忘れれば、漏れます。

- 唯一の出口で、伏せる。全部のログが通る場所に、1 つだけ置きます。

- 伏せすぎないことも、確かめる。通常のログが変化しないことを、試します。

- すでに出たものは、直しても消えない。再発行するかを、判断します。

- 外部の部品のエラーメッセージを、信じない。URL をそのまま含むことがあります。

  この話に出てくるもの

- トレカダッシュ (https://koshinstudio.com/works/torecadash/) — トレカの抽選・予約・先着の情報を集める iPhone アプリ

- Cloud Functions から月 4,300 円のサーバーへ移した (https://koshinstudio.com/notes/vps-migration/) — ログが出る場所の話

- 自分で作った仕組みが、自分を傷つけた 4 つの記録 (https://koshinstudio.com/notes/self-inflicted/) — 自分の道具の失敗

- 本物の抽選を、静かに捨てていた 4 つの実例 (https://koshinstudio.com/notes/silent-discard/) — 気づけない失敗
