Part 3 Webアプリケーション開発・動画
第14章 セキュリティの基本
動画台本ナレーション全文
Slide 01. セキュリティの基本
第14章では、Webアプリケーションのセキュリティを扱います。ここで大事なのは、攻撃の名前をたくさん覚えることではありません。自分が作った機能について、誰が、どのデータを、どの操作まで使ってよいのかを説明できることです。支援ステータス機能を題材に、守るもの、権限、入力と表示、秘密情報、依存関係を順番に見ていきます。
Slide 02. この章で持ち帰ること
この章でできるようになることは三つです。一つ目は、セキュリティ確認を怖い専門作業ではなく、普段の設計やレビューの一部として始めることです。二つ目は、認証、認可、入力、表示、ログ、依存関係を分けて見ることです。三つ目は、問題を見つけたら、修正だけで終わらせず、再発防止まで説明することです。
Slide 03. 前章までとの接続
第11章ではAPIの認証認可と入力検証を扱いました。第12章では画面のフォームとエラー表示を扱いました。第13章ではテストとコード品質を扱いました。第14章では、そこにセキュリティの見方を重ねます。新しい別世界に進むのではなく、前章までに作った設計と実装を、想定外の使われ方で問題が起きないかという視点で見直します。
Slide 04. 後から足す機能ではない
セキュリティは、リリース直前にチェックリストだけで足すものではありません。要件を決めるとき、データを設計するとき、APIを作るとき、画面を作るとき、テストを書くときに少しずつ考えます。正しい使い方なら動く、だけでは足りません。間違った入力、権限外の操作、古い依存関係、漏れた秘密情報も想像します。
Slide 05. 演習の安全な範囲
この章では、ローカルの演習用アプリだけを対象にします。実在する外部サービス、社内システム、本番環境、他者のアカウント、実データには触れません。セキュリティ学習では、試す範囲を守ること自体が重要です。うまく攻撃できるかを競うのではなく、何が問題で、どう直し、どう再発防止するかを説明できることを目標にします。
Slide 06. 資産、脅威、情報が渡る場所
セキュリティ確認は、攻撃名から始めるより、守るものから始めると考えやすくなります。資産は守りたいものです。支援メモ、支援ステータス、担当関係、Cookieやtokenなどです。脅威は起きてほしくないことです。情報が渡る場所は、外から情報が入ってきたり、別の場所へ渡ったりするところです。ブラウザからAPI、APIからDB、ログ、AIに渡す内容までを見ます。
Slide 07. OWASPの使い方
OWASPは、Webアプリでよくあるリスクをまとめた資料です。順位を暗記するためではなく、見落としを減らすために使います。ここでは全部覚えなくて大丈夫です。自分の機能に関係するリスクを探す目次として使いましょう。資料は更新されるので、研修や実務ではその時点の公式情報を確認します。
Slide 08. 認証と認可
認証は、誰であるかを確認することです。たとえばログインしているメンター本人かを見ることです。認可は、その人がその操作をしてよいかを確認することです。ログインしていることと、対象の受講者を変更してよいことは別です。この二つを混ぜると、ログイン済みなら何でもできる、という危ない設計になりやすいです。
Slide 09. API側で守る
画面でボタンを隠すことは、使いやすさのためには役に立ちます。ただし、セキュリティの最後の守りにはなりません。APIはブラウザ画面以外から呼ばれる可能性があります。担当外メンターに更新ボタンを見せないだけでなく、API側でも担当関係を確認します。画面は補助で、最後はAPI側で止めると考えてください。
Slide 10. ID直接指定のリスク
URLやリクエストの中にIDが入るAPIでは、そのIDを書き換えたらどうなるかを確認します。たとえば learnerId が 1 から 2 に変わったとき、対象が存在するかだけでなく、今のユーザーがその対象を見たり変更したりしてよいかを見ます。存在確認と権限確認は別物です。担当外データへ届く設計は、早い段階で見つけたいリスクです。
Slide 11. 認可確認例
支援ステータス更新なら、少なくとも四つの立場で確認します。担当メンターは更新できる。担当外メンターは更新できない。未ログインユーザーは使えない。受講者ロールはメンター向けAPIを使えない。この確認は画面とAPIの両方で行います。期待する返答の番号と、エラーの返し方も一緒に記録します。
Slide 12. SQLインジェクション
SQLインジェクションは、信頼できない入力がSQLの構造を変えてしまう問題です。初心者がまず見るべき合図は、ユーザー入力をSQL文字列に直接つないでいないかです。危ない文字を頑張って消す、という発想だけでは不十分です。入力をSQLの命令として解釈させないことが重要です。
Slide 13. パラメータ化クエリ
SQLインジェクション対策の中心は、パラメータ化クエリやORMの安全なAPIを使うことです。入力検証も大切ですが、入力検証だけに頼らないようにします。支援ステータスなら、許可された値だけを受け取ることに加えて、DBへ渡すときも安全な方法を使います。DBアカウントの権限を必要最小限にすることも、被害を小さくします。
Slide 14. XSS
XSSは、信頼できない入力がブラウザ上でコードとして実行される問題です。ユーザーが入力した名前、メモ、コメント、検索語などを表示するときに注意します。ここで大事なのは、入力された文字をどこに表示するかです。HTML本文、属性、URL、JavaScriptでは安全な出し方が違います。まずはフレームワークの自動エスケープを理解しましょう。
Slide 15. 支援メモの表示
支援メモを画面に表示するなら、その内容がHTMLとして解釈されず、テキストとして表示されるかを確認します。便利そうに見える innerHTML のようなAPIは、使い方を誤ると危険です。エラーメッセージや通知にも外部入力が混ざることがあります。画面の中心だけでなく、周辺の表示も同じように見ます。
Slide 16. CSRF
CSRFは、ログイン中のブラウザから、利用者が押していない更新リクエストが送られる問題です。Cookieはブラウザが自動で送るため、別のサイトからのリクエストでもログイン済みとして扱われる場合があります。Cookieでログイン状態を持つ更新APIでは、使っているフレームワークの推奨に従って、tokenや送信元の確認を入れます。
Slide 17. GETで状態変更しない
基本として、GETリクエストで状態を変更しないようにします。GETは、ページやデータを取得するためのものとして扱います。支援ステータスを変更するような操作は、POSTやPATCHなど、変更の意図が分かる方法を使います。メソッドを分けるだけで完全に安全になるわけではありませんが、事故を減らす土台になります。
Slide 18. 秘密情報
秘密情報には、API key、password、session ID、access token、private key、Cookie、Authorization headerなどがあります。ログインや外部接続に使われる鍵のようなものです。個人情報や支援メモも、見られると困る情報として慎重に扱います。ログ、スクリーンショット、PR本文、エラー出力、AIに渡す内容から漏れることがあります。
Slide 19. 漏れやすい場所
確認する場所を具体的に決めておくと、漏れに気づきやすくなります。差分、.env、.gitignore、サーバーログ、ブラウザのNetwork、PR本文、AIに渡す内容を見ます。もし秘密情報らしきものを見つけたら、消すだけでは足りない場合があります。無効化、再発防止、誰に共有されたかの確認まで考えます。
Slide 20. 依存関係
アプリケーションは、自分で書いたコードだけでできているわけではありません。多くのライブラリに依存しています。古いライブラリや脆弱性のあるライブラリは、アプリ本体のコードがきれいでもリスクになります。依存関係を書くファイルと、バージョンを固定するファイルを確認し、監査コマンドの結果を見ます。更新するときは、脆弱性修正と互換性確認の両方を見ます。
Slide 21. エラーとログ
エラーとログは、守るためにも、漏らさないためにも重要です。利用者に見せるエラーには、内部のSQL、stack trace、設定値などを出しすぎないようにします。一方で、調査に必要な時刻、操作、対象ID、結果はログに残します。ただしCookieやAuthorization header、個人情報をそのまま出してはいけません。役に立って、漏れないログを目指します。
Slide 22. AIに頼むときの注意
AIは、脅威の洗い出し、チェックリスト作成、修正案の比較、レビュー文案に使えます。ただし、入力前に秘密情報や個人情報を外し、採用前に公式資料、既存コード、ローカル実行結果で確認します。共有前やPR前にも、AIの出力をそのまま貼ってよいかを見直します。実在システムの攻撃手順は渡しません。
Slide 23. 個人開発課題への接続
個人開発課題では、自由テーマであっても、小さくセキュリティを確認する場所があります。この章では、リスクの整理、認可確認、ローカルでの再現と修正、秘密情報と依存関係の確認、レビュー文を残します。これらはPR本文や最終課題で、どこまで確認したかを説明する材料になります。第23章のProduction Readiness Reviewにもつながります。
Slide 24. Exercise 1
一つ目の演習では、セキュリティ観点を整理します。対象機能を書き、守るべき資産を書き、脅威を書きます。次に、ブラウザからAPI、APIからDB、APIからログ、開発者からAIに渡す内容へ、情報が渡る場所を書きます。最後に、優先して確認するリスクを選びます。成果物は security-risk-note.md です。
Slide 25. Exercise 2
二つ目の演習では、認可と担当外アクセスを確認します。担当メンター、担当外メンター、受講者ロール、未ログインユーザーで、一覧を見る操作と支援ステータス更新を確認します。IDを書き換えた場合の期待結果と実際の結果も記録します。成果物は authorization-check.md です。
Slide 26. Exercise 3
三つ目の演習では、ローカル演習用アプリで脆弱性を再現し、修正します。対象はSQLインジェクション、XSS、CSRFの基本例です。実在環境では絶対に行いません。脆弱な実装、ローカルで再現したこと、原因、修正方針、修正後の確認、再発防止を書きます。成果物は attack-and-fix-log.md です。
Slide 27. Exercise 4
四つ目の演習では、秘密情報と依存関係を確認します。まず、差分、ログ、PR本文、AIに渡す内容に、秘密情報が混ざっていないかを見ます。次に、依存関係を書くファイル、バージョンを固定するファイル、監査コマンドの結果を確認します。対応することと、今回は対応しない判断を分けて書きます。成果物は secrets-and-dependencies-check.md です。
Slide 28. Exercise 5
五つ目の演習では、セキュリティレビューを書きます。対象変更、確認したリスク、修正したこと、実行したテストや手動確認、残したリスク、PRに書くことを整理します。完璧に安全です、と言い切るためではありません。どこまで確認し、何を残課題にしたかを、レビュアーが追える形にするためです。
Slide 29. まとめ
この章では、守るものから考え、認証と認可を分け、入力と表示を確認し、秘密情報と依存関係まで見ました。セキュリティは怖い言葉に見えますが、最初の一歩は日々のレビューに近いです。何を守るか、どこで情報が渡るか、どの証拠で確認したか。この三つを言えるようにしましょう。
Slide 30. 第15章への接続
次の第15章では、コンテナと実行環境を扱います。セキュリティ観点は、アプリをどこで、どんな設定で、誰の権限で動かすかにもつながります。環境変数、ポート、volume、image、依存関係、実行ユーザーなどは、次章で順番に整理します。第14章で見た、守るものと情報が渡る場所の考え方を持ったまま進みましょう。