LoginSignup
0
1

More than 3 years have passed since last update.

PHP For Beginnersチュートリアル その2 CSRFについて学び、基本的な設定をしてみる

Last updated at Posted at 2019-07-16

このシリーズの目的

体系的なwebコーディングの訓練ができるようになるために、PHPの初学のきっかけかつ、PHPでログインフォームやフォームを実装することができるようになるために

PHP For Beginners

上記のチュートリアルを進めているのでその備忘録。

前回

内容

今回のチュートリアル

PHP Security Tutorial: Cross-Site Request Forgery (CSRF) Protection

やったこと

CSRFとは何かを知り、その対策について基本的なコードを書きながら確認する。

成果物

csrf.php
<?php 

    // session start

    session_start();

    // create a key for hash hmac funciton

    if(empty($_SESSION['key']))
        $_SESSION['key'] = bin2hex(random_bytes(32));

    // echo $_SESSION['key']; // 生成されたキーの確認。本番では記載しない。

    // create CSRF token

    $csrf = hash_hmac('sha256', 'this is some string: csrf.php', $_SESSION['key']);

    // validate token(正常にCSRFトークンが生成されているか確認)

    if(isset($_POST['submit'])) {
        if(hash_equals($csrf, $_POST['csrf'])) {
            echo "your name is:" .$_POST['username'];
        } else
            echo "CSRF Token Failed";
    }



 ?>

<!DOCTYPE html>
<html>
    <head>
        <title>CSRF Tutorial by CPI</title>
    </head>
    <body>
        <form action="csrf.php" method="POST">
            <input type="text" name="username" placeholder="what is your name?">
            <input type="hidden" name="csrf" value="<?php echo $csrf ?>">
            <input type="submit" name="submit" value="SUBMIT">
        </form>
    </body>
</html>

新しい用語

CSRF(クロスサイトリクエストフォージェリ)
→Webアプリケーションの脆弱性・またそれを利用した悪意のある攻撃を指す。

*対策にはワンタイムトークンを使用する。
なので今回は不可逆性を持つハッシュ関数が利用されているということになる。

今回のコードの注釈


session_start();
新たなPHPのセッションを開始するかあるいは既存のセッションを再開する


    if(empty($_SESSION['key']))
        $_SESSION['key'] = bin2hex(random_bytes(32));

emptyは引数に指定した変数が空であるか確かめる
bin2hex(random_bytes(32));はバイナリのデータを16進表現に変換したASCII文字列にして返すコマンドで今回は32バイトで生成したランダムバイナリを変換することになる

つまりif文で書いてあるのでこの場合キー変数が空だった場合は32バイトのランダムバイナリを生成してそれを16進表現に変換したASCII文字列に変換しそれを代入するということになる
$csrf = hash_hmac('sha256', 'this is some string: csrf.php', $_SESSION['key']);

hash_hmac()はHMAC方式を使用してハッシュ値を生成するコマンド
引数に使用するアルゴリズムハッシュするメッセージ生成するために使用する共有の秘密鍵を指定する

sha256とはハッシュ関数を別の値に変換するアルゴリズムの一つ
ハッシュ関数は変換し値をもとに戻す方法が無いという不可逆性を持つ

    if(isset($_POST['submit'])) {
        if(hash_equals($csrf, $_POST['csrf'])) {
            echo "your name is:" .$_POST['username'];
        } else
            echo "CSRF Token Failed";
    }

issetは変数がセットされかつnullじゃないことを確認するコマンド
この場合後述するHTMLのフォーム要素において送信ボタンが押されフォームの情報が取得できたかできないかで分岐が変わる
取得したハッシュ値が一つ前で生成されたCSRFトークンの値と等しければ取得したname属性の情報をyour name is:の文字列に加えて出力する
等しくなければエラーメッセージを出すということになる

学習済みの知識の復習



        <form action="csrf.php" method="POST">
            <input type="text" name="username" placeholder="what is your name?">
            <input type="hidden" name="csrf" value="<?php echo $csrf ?>">
            <input type="submit" name="submit" value="SUBMIT">
        </form>
    </body>
</html>

送信ボタンと1行の入力欄を作る、基本的なフォームのマークアップ。
inputタグなどは必ずtype属性とname属性を指定して、役割を明確にする。
このうち、type = hiddenは画面上に表示されない隠しデータをやり取りするための属性である。
今回は送信する値にphpで生成した変数csrfをphpで出力したもので指定している。

広がった知見

CSRFとその対策について理解し、暗号キーの生成方法とハッシュを生成する方法を学習できた。

参考

サイトを安全に!PHPでcsrf対策を行う方法【初心者向け】
PHPでSHA256を使う方法【初心者向け】
HTTPとPOSTとGET
GETとPOSTの使い分け方法

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1