全国オンライン対応受付 平日 9:00-18:00
お問い合わせ

開発記録 / toi-toi-toi制作記 / Vol.33 toi-toi-toi制作記 Vol.6

記事 05

既定値のまま動いていた——本番を止めずに鍵を入れ替える

ADMIN_PASSWORD = os.getenv("TTT_ADMIN_PASSWORD", "toitoi2024admin") GAS_ADMIN_SECRET = os.getenv("GAS_ADMIN_SECRET", "ttt-gas-admin-2024-secret")

2026-06-13 公開

監査の三つ目の指摘は、こうだった。

「管理認証情報の既定値が固定されている」

コードには、こう書いてあった。

ADMIN_PASSWORD   = os.getenv("TTT_ADMIN_PASSWORD", "toitoi2024admin")
GAS_ADMIN_SECRET = os.getenv("GAS_ADMIN_SECRET", "ttt-gas-admin-2024-secret")

環境変数があればそれを使う。無ければ、引数の右側、固定の文字列を使う。安全な書き方のつもりだった。

サーバーを調べた。環境変数は、設定されていなかった。つまり本番は、ずっと右側で動いていた。ソースを読めば誰でも分かるパスワードと、誰でも分かる共有鍵で。


共有鍵は、両側で同時に変える

パスワードを変えるのは簡単だ。だが GAS_ADMIN_SECRET は厄介だった。これは、サーバー(app.py)と、その先のGAS、二つの場所で同じ値を持つ「共有鍵」だ。サーバーがこの鍵を付けてGASを呼び、GASが鍵を確かめて応える。

片方だけ新しい鍵に変えると、もう片方は古い鍵を待っている。合わない。管理画面の操作が、全部はじかれる。

新旧どちらの鍵も受け付ける、という重なりの時間を作る仕組みは、入れていなかった。だから、切り替えの瞬間だけは、どうしても管理APIが一瞬止まる。二つの鍵を、できるだけ近いタイミングで、両側そろえて入れ替えるしかない。

手順を決めた。GAS側に新しい鍵を設定する。すぐにサーバー側の環境変数も新しい鍵にして、再起動する。この間の一、二分、管理画面だけが整合を失う。予約の受付やLINEは、この鍵を使わないので止まらない。止まるのは、自分が触る管理画面だけ。だから、止めていい時間だった。


既定値を消す、ということ

入れ替えと同時に、固定の右側を消した。

ADMIN_PASSWORD = os.getenv("TTT_ADMIN_PASSWORD")
if not ADMIN_PASSWORD:
    raise RuntimeError("環境変数が未設定です")

既定値を消すと、設定を忘れたときにサーバーは起動しなくなる。一見、不便だ。だが、これでいい。「設定し忘れても、とりあえず既知の値で動いてしまう」より、「設定されていなければ、はっきり止まる」方が、ずっと安全だ。静かに弱いまま動き続けるのが、一番こわい。

GASの中に直書きされていたLINEのトークンも、秘密の保管場所へ移した。エディタの編集途中にできた一時ファイルにも、古いトークンが残っていた。それも消した。ソースに書いた秘密は、本体から消しても、影のように別の場所に残る。


401と、200

切り替えのあと、確かめた。

新しいパスワードでログイン――通る。古いパスワードでログイン――401、拒否。管理画面からイベント一覧を取る――200、ちゃんと二件返ってくる。共有鍵は、両側で新しい値にそろっていた。本番のGASから、直書きの秘密は、一つも検出されなくなった。

監査が指摘するまで、この弱さは「動いている」という顔をして隠れていた。動くことと、守られていることは違う。別のAIが、その違いを三つ、はっきり指さしてくれた。


これで予約システム制作記 Vol.6は終わり。画面のボタンから、見えないスタイルの漏れ、AIに読まれる文章、そして外から来るものをどう信じるか。一つの予約システムの中に、これだけの問いが詰まっていた。

シンプルシステム株式会社 代表 伊藤勝彦