🔒

Next.jsで実装する場合に、セキュリティ面で気を付けること

2024/11/11に公開

はじめに

以下のYoutubeで解説されていた内容が勉強になったのでまとめた。

https://www.youtube.com/watch?v=LolugLiLhHs

ポイント

・Propsで渡す情報に気を付ける

・SeverActionsに注意する

・認証チェックをする場所について

Propsで渡す情報に気を付ける

Next.jsでは、サーバーコンポーネントと、クライアントコンポーネントがある。

例として、サーバーコンポーネント内で、ユーザー情報を取得して、クライアントコンポーネントにその値を渡してしまった場合、本来見られてはいけないユーザー情報がブラウザで見ることが可能になるので、とても危険な状態となる。

対策としては、「クライアントコンポーネントに余計な情報は渡さない。」ということ。

具体的な対策としては、以下の2点が挙げられる。

・SQLのSELECTのフィールドを必要最低限にする。

・DTOを使う。DTOについては以下のサイトに詳細が記載されている。

https://qiita.com/RINYU_DRVO/items/112957b84ec8c2a4711a

SeverActionsに注意する

具体的には、ServerActionsに渡す引数に注意する。ServerActionsは、ブラウザからAPIをfetchしているに過ぎないので、引数にユーザー情報(ユーザーID)などを渡して、それを元に処理を行う関数を実装してしまうと、クライアントからそのAPIに対して、自分以外のユーザーIDを渡して、ServerActions内の関数を呼べることができてしまうため、とても危険な実装といえます。

なので、ServerActionsを利用する場合は、権限やセッションのチェックなどは外部で行わず、関数内でチェックをするようにするのが良い。

認証チェックをする場所について

ログインなどの機能があった場合に、認証、認可のチェックをどこで行うべきか?

Middleware、layout component、page componentなどの選択肢があるが、基本的には各page componentで行うのが、一番確実な方法となる。

理由としては、以下が挙げられる。

  • Middlewareファイルでは、Edge Runtimeという、Web標準の機能でしか動かないようになっているため、Node.jsの全ての機能が使えず、SQLを実行することができない。

  • layout componentは、page componentの後にレンダリングされるため、layout componentで認証や認可のチェックをしていない場合、画面上は動くかもしれないが、一時的にでもチェックを通過しないと見られないデータが、クライアントで取得されてしまうので、とても危険である。
    また、layout componentは、ページ遷移しても再レンダリングされないため、画面遷移した時に、チェックがされないため、それも危険な要因の一つとなる。

以上の理由から、認証や認可のチェックは、各page componentで行うことが確実となる。

また、「updateUser」のような関数があった場合は、その情報操作をする関数内でチェックを行うのが良い。

まとめ

Next.jsは、とても便利なフレームワークだが、使い方や機能をしっかり理解していないと、とても危険なアプリケーションを作成することができてしまうため、改めてしっかりキャッチアップする必要があるなと思った。

Discussion