はじめに
今回はWebアプリケーション開発におけるCookieやSession、Session周りの説明と基本的なセキュリティ対策について備忘録がてら記事を書いていきたいと思います。
まずはCookieやSession周りについて書いていき、その後に基本的なセキュリティ対策について書いていきたいと思います。
今回はPHP、HTML、SQLを使用して書いていきます。
対象者
- 未経験エンジニア
- エンジニア1~2年目
- セキュリティ対策についての理解が浅い方
- CookieやSessionについての理解が浅い方
CookieとSessionについて
以降で説明していくセキュリティ対策を理解するには、まずはCookieやSession周りの仕組みを知ることが重要なので、まずはCookieやSession周りについて書いていきます。
Cookieについて
Cookieとは、ブラウザとサーバとの一連のやり取りにおける状態管理を保持するために必要なデータのことです。
ユーザがブラウザにアクセスした時、サーバは画面と一緒にブラウザ側に保存してほしい情報をCookieとして送信します。
例えば、どのブラウザからアクセスしてきたのか分かるような識別情報であったり、保存期間などです。
Cookieを受け取ったブラウザは次にサーバ側にリクエストを送る際に情報と一緒にCookieを送ることでサーバ側はどのブラウザから送られてきたのかを識別できるようになります。
ここで重要になってくるのがSessionIDです。
SessionIDとは、サーバー側に保存されたSessionを識別するためのIDのことです。つまり、ブラウザがサーバ側にリクエストを送信した時、サーバ側は送られてきたCookieの中に入っているSessionIDとサーバ側に保存してあるそのブラウザのSessionIDが一致しているかどうかを照合します。一致した場合は情報を処理しレスポンスを返します。
また、Webアプリケーションではトークンと呼ばれる値を利用することがあります。
トークンとは、認証やリクエストの検証など、特定の目的のために利用される値のことです。例えば、CSRF対策ではCSRFトークンを利用し、正規の画面から送信されたリクエストであるかを確認します。
Sessionについて
Sessionとは、ユーザーごとの状態をサーバー側で保持する仕組みをSessionといいます。
基本的なセキュリティ対策
- XSS(クロスサイトスクリプティング)対策
- CSRF(クロスサイトリクエストフォージェリ)対策
- SQLインジェクション対策
- Session固定攻撃対策
XSS(クロスサイトスクリプティング)対策
まずはXSSについておさらいです。
XSSとは、入力画面等に悪意あるスクリプトを埋め込み、ユーザがそこにアクセスした瞬間にスクリプトが実行され、例えばユーザのブラウザ側に保存されていたSession IDが盗まれ、Sessionハイジャックされてしまう攻撃のこと。
となります。
これの対策としては、悪意あるスクリプトをただの文字列として認識させ実行できないようにします。
// 実装例:PHP
// HTMLとして出力する箇所では、ユーザーから受け取った値を適切にエスケープします。
$original_str = $_POST['user_input']; // 例:ユーザが入力する値
echo htmlspecialchars($original_str,ENT_QUOTES,"UTF-8")
CSRF(クロスサイトリクエストフォージェリ)対策
まずはCSRFについておさらいです。
CSRFとは、ユーザがログイン中のまま、悪意あるサイト(トークンを保持していないサイト)にアクセスすると、ユーザ側のサーバに勝手にリクエストが送信されてしまうなどユーザになりすまして操作されてしまう攻撃のこと。
となります。
これの対策としては、正規の画面から送信されたリクエストであることを確認するために、予測困難なCSRFトークンを利用します。
また、サーバ側にあるトークンとブラウザ側にあるトークンとを照合させるようにもします。
<!-- 実装例:HTML -->
<input type="hidden" name="token" value="<?php echo htmlspecialchars($_SESSION['sstoken'],ENT_QUOTES,"UTF-8"); ?>" />
SQLインジェクション対策
まずはSQLインジェクションについておさらいです。
SQLインジェクションとは、攻撃の入り口(入力フォーム)はXSSと似ていますが、攻撃対象がDBになります。入力フォームに悪意あるSQLを入力してリクエストを送ることで、DB情報などを盗み取る攻撃のこと。
となります。
これの対策としては、DBにSQLを送るときにSQLの命令文とデータを分離して処理することで、文法を改ざんさせないように、勝手に悪意あるSQLを実行できないようにします。
// 実装例:PHP(SQL)
// DB接続情報
$param = 'mysql:dbname='.DB名.';host='.DBホスト名;
// DBに接続
$pdo = new PDO($param, DBユーザ名, DBパスワード);
$pdo->query('SET NAMES utf8');
// 空のSQL準備
$sql = "select * from user where user_id = :user_id";
$stmt = $pdo->prepare($sql);
// 値を入れる
$stmt->execute(array(":user_id"=>$_POST['user_id']));
Session固定攻撃対策
まずはSession固定攻撃についておさらいです。
Session固定攻撃とは、攻撃者があらかじめ用意したSession IDを攻撃対象のサイトのURLに含ませて、それをユーザに踏ませてログインに成功した瞬間に乗っ取りが成功し、ユーザになりすまされる攻撃のこと。
これの対策としては、認証状態が変わるタイミングで新しくSession IDを生成し直すことで攻撃者が用意したSession IDを利用できなくするようにします。
// 実装例:PHP
session_regenerate_id(true);
おわりに
今やAIがコードを書く時代となり、エンジニアの役割も「AIが生成したコードをレビュー・選定する」方向へと変化してきています。
そんなAI時代になぜCookieやSessionの仕組み、セキュリティの基礎を学ぶ必要があるのか。持論になりますが、「AI時代だからこそ、基礎知識の重要性がより高まっているから」だと考えています。
確かにAIは非常に優秀で、人間よりも圧倒的なスピードでコードを書いてくれます。しかし、生成されたコードがセキュリティ的に安全か、アーキテクチャとして適切かを判断して責任を持つのは、まだ人間の役割です。
基礎的な仕組みの理解や正しい知識がなければ、AIが提示したコードの良し悪しを判断すること(レビュー)すらできません。AIという強力なツールを安全かつ最大限に使いこなすためにも、こういった基礎技術の理解をこれからも大切にしていきたいと思います。