転職用のポートフォリオとして、個人でWebアプリ「Hubpin」を作っています。
制作の経緯は「Hubpin 開発記録」に時系列でまとめています。
設計と判断は自分で行い、実装も原則自分で書いています。AIには手順書・レビュー・調査を任せています。
公開したあと、セキュリティまわりの手直しをまとめてやる回がありました。
手順書はAIが書き、自分はそれに沿って作業します。
その手順書に、こういう欄がありました。
「見るもの / 予想(推測なので、違ったら記録する)」
対象は、本番でログインしたときにブラウザへ発行される cookie の属性3つです。
cookie の属性は、その cookie をどう扱ってよいかをブラウザに伝える印で、セキュリティに直接関わります。
AIが先に予想を書いておき、自分がブラウザの開発ツールで実際の値を見て、答え合わせをする形でした。
結果は、3つのうち2つが外れでした
| 属性 | 意味 | 予想 | 実測 |
|---|---|---|---|
| HttpOnly | ページ内のスクリプトから cookie を読めなくする | 付いている | 付いていない |
| Secure | HTTPS の通信でしか cookie を送らない | 付いている | 付いていない |
| SameSite | 他サイトからのリクエストに cookie を付けるかの範囲 | Lax | Lax(予想どおり) |
正直に言うと、自分も「付いていて当然」の属性だと思っていたので、3つとも当たると思って見に行きました。
認証ライブラリが標準で付けてくれるものだと思い込んでいました。
でも、外れたことに意味がありました。
当たっていたら、何も残らなかった
もし3つとも当たっていたら、「推測でも合っていた」で終わっていたと思います。
そして次も推測で書きます。
確かめなくても合うという経験が、確かめない癖を強くします。
外れたので、手順書にこう書けるようになりました。
「この2つは推測が外れた。だから次は測ってから書く。」
手順書には「合っていても外れていても、実測したと書けることに意味がある」と先に書いてありました。
書いたのはAIですが、自分もそのとおりだと思って測りに行きました。
そのとおりになりました。
外れたほうから、別の問題が出てきました
HttpOnly が外れたことで、元の課題票の書き方に問題があるとAIから指摘がありました。
課題票には、この属性についてこう書いてありました。
「HttpOnly を有効にしても、問題は1ミリも解決しないので対応しない」
この課題票の「問題」は、ブラウザの開発ツールから誰でもトークンを取り出せる、という話でした。
開発ツールからは HttpOnly の cookie も見えるので、付けても防げない。
その意味では正しいです。
でも実際には、HttpOnly は最初から付いていませんでした。
| 書いた根拠 | 「有効にしても防げない」 |
| 実態 | 「もう有効ではない」 |
結論は同じです。
対応しない、という判断は変わりません。
でも、根拠の向きが逆でした。
「有効でも防げない」と「有効ではない」は、読む人にとって別の情報です。
前者を読んだ人は「有効になっている」と思って先に進みます。
課題票を読んだ自分が、そうでした。
同じ形のずれを、この日は他でも2回見ました。
結論は合っているのに、その理由が違っている。
結論だけ見ていると気づかない種類のずれです。
予想欄を1行増やすだけ
予想を書かずに測ると、何が出てもそれが答えに見えるので、「まあそんなものか」と思って終わります。
予想を書いてから測ると、外れたところだけが目に飛び込んできます。
比べる相手が先にあるので、ずれが形になります。
やったことは、手順書の表に列を1つ足しただけです。
測る前に、そこに思い込みを書いておく。
それだけで、確かめる作業が「答え合わせ」に変わりました。
次からは、AIに手順書を頼むとき、自分から「予想欄を作って」と言うことにしました。
