あかね
無知の無知は罪かも🥹徳丸本で学ぶセキュアなWeb設計
2026年02月25日
見出しはありません
要約を生成中...
ShiftBでは11章から認証認可について学び、401返すとか、権限不足なら403や404返すとかそういった、基本的なセキュリティを学びます。
私もしっかり理解して(とはいってもJWTって何レベルでトークンの検証結果を見ているだけで内部で起きていることまでは知りませんでしたが)、できるって自負がありました。
でも!!!!実務が始まって認証基盤を担当する中で無知の知の連続で衝撃を受けました。
「それはセキュアじゃない!」「平文保存ダメ!」「暗号化!」「漏洩したら会社終わる!」って何回言われたことか😭
cookieの属性も何も知らないでよくできると思ってたなって今となっては思います。
セキュリティ弱弱と自覚してWEBエンジニアのバイブルらしい徳丸本とやらを買ってみました。
体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践
ということで学んだことをアウトプットします。皆さんの無知の知のきっかけになればと思います。
設計はトレードオフの連続です。隙の全くない完璧な設計なんて100%無理です。
ただ、知らないのは違うと思います。
当たり前のこと書きます。
利用者がいた場合は金銭的損失の補償
迷惑料の発生
停止による機会損失
信用無くなり売上減少
個人情報保護法に個人情報を預かる場合には安全管理措置を講じる義務があります。
知らなかったではすみません、、
億単位の損害賠償とかなったら人生が終わってしまうかもしれません。コワ〜〜〜
主の原因はクッキー発行の際の属性に不備があることです。
これめちゃ仕事でやったので気をつけてます。
### 1. Secure
- HTTPS通信時のみCookieを送信する
- HTTPでは送信されない
- 本番環境では必須
- 中間者攻撃(MITM)による盗聴リスクを低減
Set-Cookie: session_id=xxx; Secure;
### 2. HttpOnly
- JavaScriptからアクセス不可(document.cookieで取得できない)
- XSSによるトークン窃取を防ぐ
- 認証系Cookie(session_id / refresh_tokenなど)は必須
Set-Cookie: session_id=xxx; HttpOnly;
### 3. SameSite
クロスサイトリクエスト時にCookieを送信するかを制御
- Strict
完全に同一サイトのみ送信
CSRF耐性が最も強いが、外部リンク遷移後などに不便な場合あり
- Lax(現在の多くのブラウザのデフォルト)
通常のナビゲーション(GET遷移)のみ送信
多くのWebアプリでは推奨バランス
- None
クロスサイトでも送信
Secure必須
OAuthや外部ドメインを跨ぐ場合に使用
Set-Cookie: session_id=xxx; SameSite=Lax;
### 4. Domain
- Cookieを送信する対象ドメインを指定
- サブドメイン共有時に利用
- 不要に広く設定するとリスク拡大
### 5. Path
- どのパス配下でCookieを送信するか指定
- 原則 "/" を指定することが多い
Path=/
### 6. Max-Age / Expires
- Cookieの有効期限
- セッションCookie(未指定)はブラウザ終了で削除
- 長期間のアクセストークン保存はリスク
Max-Age=3600
Expires=Wed, 01 Jan 2026 00:00:00 GMTブラウザから読めるcookieに認証情報を入れるのはXSS攻撃を喰らいやすくなるので論外です。
必ずHttpOnlyにすることが重要です。
、、、HttpOnlyごときw
localStrageはJSから読めるので大事な情報を入れてはダメです🙅♀️
クロスサイト・スクリプティング(XSS)
HTML生成の箇所に問題がある場合に脆弱性が発生します。
攻撃者の用意したJSが実行されると、Cookieを盗まれる可能性があります。
HttpOnlyを付けていれば document.cookie からは取得できませんが、それでもDOMの改ざんや、意図しないAPI実行などは可能です。
「HttpOnlyだから安全」ではなく、XSS自体を発生させないことが重要です。
偽の入力フォーム表示されてカード情報盗まれることもあるとか、、、恐ろしい、、、
用意した画面書き換えられて、わけわからんところに内容送信されるかも思ったら怖くて私は夜しか眠れないです。
XSSに関しては本の中でも詳しく解説や攻撃パターン、防ぎ方のパターンが書いてあり、ボリュームありました。
エラーメッセージからの情報漏洩
ブラウザで見れるconsole.logにサーバーから返ってきたログをそのまま出すのはしない方がいいです。
「失敗しました」とか決まった文字だけ出しておいて、サーバー側のログでエラー内容がわかるようにしないとセキュアではないです。
サーバー側から届いたメッセージそのまま表示はNGです!
クロスサイト・リクエストフォージェリ(CSRF)
ユーザーがログイン中の状態を悪用し、 攻撃者が用意した別サイト経由で意図しないリクエストを送信させる攻撃です。
Cookieベース認証が自動送信されることを利用するため、SameSite属性やCSRFトークンで防御します。
防ぐのはサーバー側で正当なリクエストか判定する処理をしっかりすることです。
認証はアプリケーションの利用者が本人であることをなんらかの手段で確認することです。
ログイン時のパスワードの入力するプロセスでの攻撃がたくさんあります。
アカウントロックが有効です。(ユーザーの立場だと不便に感じたりもしますが、、)
総当たり攻撃にもたくさん種類があるようで、辞書攻撃、ジョーアカウント探索、逆総当たりなどなど、、あの手この手で乗っ取ろうとしてきますね。
基本supabaseやCognitoなその認証用の外部サービス使って、パスワードは自社DBで持たないか、ライブラリなどで暗号化して保存すると思います。
「平文で保存しない。」これ結構言われるところで、万が一!DBのデータが流出しちゃったとしたときに暗号化されたデータであれば鍵がないと復元できない、意味わからないただの文字列になり、ダメージが最小限になります。
なのでDMとかメッセージの機能はLINEとかもやってますけど暗号化されているデータをDBに持つ設計のアプリケーションも少なくないみたいです。
ユーザー同士でどんな会話しているかわかんないし、サイトのログイン情報入ってたり、住所生年月日氏名、電話番号などなど、、、自由な分だけどんなリスク潜んでるかわからないので暗号化して保存しておくとしないよりはセキュアになります。
パスワードのように復元する必要がないデータはハッシュ化が基本です。
一方で、DMや住所など復元して利用する必要があるデータは暗号化が必要になります。
暗号化すればOKではなく、データの性質に応じて適切な保存方法を選ぶことが重要です。
なんでもかんでも暗号化はしてないです!住所はしたことないです!
多くの開発者が「隠しているつもり」の秘密が、DevTools一つで丸裸にされているかもしれません。
JavaScriptの変数、ビルド時に埋め込まれた環境変数、APIのURL。これらはすべて、ユーザーの手元に届いた瞬間にユーザーの持ち物です。
「難読化しているから」「パッと見ではわからないから」という言い訳は、徳丸本の視点から見れば、金庫の鍵を透明なビニール袋に入れて玄関に吊るしているのと同じです。
クライアントサイドに隠し場所はないということを覚えておきたいです。
もちろんトレードオフです。理解しておくことが大事
徳丸本的に言えば、ブラウザは敵地です。
JavaScriptはユーザーの手元に届いた瞬間、ユーザーの持ち物になります。
その意味で、Next.jsのServer Componentは非常に思想的です。
デフォルトがサーバー実行、つまり自分のテリトリーで処理を書けるということです。
"use client"を付けるたびに、わざわざ敵地にロジックを置いていることを自覚するべきです。
サーバーコンポーネントはhooks使えないので完全にトレードオフです。
本当に知らないことばかりです。
まだ本も全部読めてないです。一部だけですがアウトプットしました。
全部を一気に理解は私もできませんが、理解して対策しようとする義務はプロダクト開発をしているエンジニアなら必須だと思います。
だからこそ、知らないことを知らないままにしない。
まずは自分の無知の知を増やすことが、最低限の責任だと感じています。
私は新卒で銀行に就職したこともあり個人情報の取り扱いは特に厳しく叩き込まれる業界で育っているので、セキュリティは怖くて怖くて仕方ないです、、
でも仕事で責任持って開発できるように学習継続します!
要約
コメント
まだコメントはありません。