はじめに
どうも皆さん、おはこんばんにちは!
シーエーアドバンスで脆弱性診断チームの脆弱性診断員をやっております。
@ihahajimeです。宜しくお願いします!!
いやー、この季節がやってまいりましたね!
え?クリスマス?いいえ シーエー・アドバンス Advent Calendar 2020 の6日目です
今回は「やられサイトができるまで ~開発編~」ということで、
今学生向けインターンに向けて絶賛開発を進めている「やられサイト」を構築する時に、
開発面からみて大変だったことや学びになったことを備忘録として書きたいと思います。
脆弱性を組み込むあたりの話は、「脆弱性編」で書いていければと思います。
開発も記事を書くのも未熟なので、温かく見守っていただければと思います
やられサイトとは
「やられサイト」とは、予め脆弱性が組み込まれたサイトのことで、
セキュリティの学習やツールなどの検証、脆弱性のデモなどに良く用いられたりするWebサイトのことです。
去年の僕の記事でOWASP Juice Shopを紹介していますので、気になった方はそちらを参照してみてください!
 気軽に脆弱性を見つけてみよう! - Qiita
気軽に脆弱性を見つけてみよう! - Qiita
環境とか
Laradockを利用しています。
下部の[参考にした記事など] (https://qiita.com/drafts#%E5%8F%82%E8%80%83%E3%81%AB%E3%81%97%E3%81%9F%E8%A8%98%E4%BA%8B%E3%81%AA%E3%81%A9)を参照してください。
また、同じチームのメンバーと作業を手分けをしていて、自分は主にバックエンドの作業を行っています。
フロントエンドの作業は@miya_zatoくんが担当してくれています
12日に記事担当なので、きっと面白い記事を投稿してくれることでしょう...
┗追記:[kali linuxでhydraを使ってパスワードクラックをしてみた] (https://qiita.com/miya_zato/items/0c32dc71208460515e34)
コーチは@sk888さん、監督は@toubaruさんです
担当した作業で大変だったことやあれこれ
・DB設計
・JWT認証を入れたAPI実装
そもそもWebアプリケーションの開発経験がとても浅く、知識もそこまでないので、基礎から学習し進めていきました。
DB設計やAPIの作成、認証の導入などなど学びはたくさんありました...!
typoや変数ミスなどしょーもないミスもたくさんありました... そこは慣れていきたいと思います。
そこは慣れていきたいと思います。
DB設計
記事が投稿できるようなサイトを作っていこうというところで、
このサイトではどのようなテーブルが必要でどのようなカラムが必要...といった部分から考え始めました。
まずはマイグレーションファイルを必要分用意、例で記事用のテーブルを1つだけ記載しています。
下記でカラムの内容を決めているのですが、どのカラムがどの型でどのような制約をつけて...という部分ですごく悩みました...
  //articlesテーブル作成
  Schema::create('articles', function (Blueprint $table) {
      $table->increments('id');
      $table->text('title')->nullable();
      $table->text('content')->nullable();
      $table->integer('price');
      $table->integer('user_id')->unsigned();
      $table->timestamps();
      //外部キー制約
      $table->foreign('user_id')
          ->references('id')->on('users')
          ->onDelete('cascade');
  });
記事用のテーブルなので、テーブル名は「articles」にし、次いで記事に必要な項目を考えました。
・タイトル(title)
・本文(content)
・有料記事用の値段(price)
・投稿者と紐づける為のユーザーID(user_id)
こんな感じかな...あと、usersテーブルと紐づける為に外部キー制約も記載しています。
それに合わせてModelの作成とControllerの作成。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
  //記事テーブルの内容
    protected $fillable = [
        'title', 'content', 'price','user_id',
    ];
}
下記は記事を登録して登録した内容を返す処理のControllerの一部です。
バリデーションチェックの方法や今回APIなのでjson形式で値を返す方法など勉強になりました。
※最大値とかは仮に設定してあるものです。
    protected function articleregister(Request $request)
    {
        if($this->validator(request()->all())->fails()) {
            return response()->json(['message' => $this->validator(request()->all())->messages()], 422);
        }
        $message = $this->create(request()->all());
        return response()->json($message, 200);
    }
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'title' => 'required|string|max:255',
            'content' => 'required|string|max:255',
            'price' => 'required|integer|min:0|max:500',
            'user_id' => 'required|integer|exists:users,id',
        ]);
    }
    protected function create(array $data)
    {
        return Article::create([
            'title' => $data['title'],
            'content' => $data['content'],
            'price' => $data['price'],
            'user_id' => $data['user_id'],
        ]);
    }
postman等のAPI確認できるツールで、必要なパラメータをセットしPOSTで投げると、
登録した内容がJSON形式で返ってくるようになりました
JWT認証を入れたAPI実装
また、認証機能としてJWTを導入しています。
jwt-authの実装自体は参考にしたサイト通りに進めていけば問題なく導入でき、access_tokenが返ってくるところまで確認できました。
(サイトを参考に進めただけなので、手順等の記載は割愛します)
api.phpのルーティングでうまくハンドリングできるかどうかが通常のweb.phpのルーディングとは違う感じでした。
config/auth.phpを下記のように設定
        // jwttokenを使いたいので web を api に変更
        'defaults' => [
            //'guard' => 'web',
    	    'guard' => 'api', 
            'passwords' => 'users',
        ],    
        'guards' => [
           'web' => [
                'driver' => 'session',
                'provider' => 'users',
            ],
            'api' => [
                // 'driver' => 'token',
    		'driver' => 'jwt',
                'provider' => 'users',
                'hash' => false,
            ],
        ],
guardsのAPIのドライバーをjwtにしたあと、そのAPIをdefaultsのguardにしてます。
それに合わせ、guestとauthで振り分けています。
下記はログインや会員登録など、認証前のルートで使用しているグループの設定。
Route::group([
    "middleware" => "guest:api",
], 
下記はログイン後に記事を登録したりなど、認証後のルートで使用しているグループの設定。
Route::group([
    'middleware' => 'auth:api'
], 
ログイン後のルーティングをこのグループに書くことによって、jwtドライバを使って認証ができるようになりました!
セッション切れたらエラーになるのでハンドリングする設定も必要ですね!(まだ追加していない )
)
...と、まぁこんな感じで色々学習していってサイトを構築していっています!
参考にした記事など
・5.5 Laravel
・Laradock公式サイト
・Laradockを使ってLaravel 5.5環境を構築する - Qiita
・Windows10でLaradockを使ってLaravel 5.5環境を作る
・【2020年4月 時点】LaravelでJWT認証! jwt-auth 導入手順|ProgLearn
まとめ
まだサイトを構築する段階なので、これから作りこんで、脆弱性を組み込めていけたらと思っています。
完成したら次は脆弱性編としてまた紹介させていださきますね!こうご期待ください!
記事を書く経験がほとんど無いし、開発の知識もまだ浅いので、
至らない箇所あれば容赦なく指摘していただければ嬉しいです!
最後までありがとうございました それでは次の記事でまた!良いお年を
それでは次の記事でまた!良いお年を