Next.jsで実装する場合に、セキュリティ面で気を付けること
はじめに
以下のYoutubeで解説されていた内容が勉強になったのでまとめた。
ポイント
・Propsで渡す情報に気を付ける
・SeverActionsに注意する
・認証チェックをする場所について
Propsで渡す情報に気を付ける
Next.jsでは、サーバーコンポーネントと、クライアントコンポーネントがある。
例として、サーバーコンポーネント内で、ユーザー情報を取得して、クライアントコンポーネントにその値を渡してしまった場合、本来見られてはいけないユーザー情報がブラウザで見ることが可能になるので、とても危険な状態となる。
対策としては、「クライアントコンポーネントに余計な情報は渡さない。」ということ。
具体的な対策としては、以下の2点が挙げられる。
・SQLのSELECTのフィールドを必要最低限にする。
・DTOを使う。DTOについては以下のサイトに詳細が記載されている。
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