😱

Server Actions はクライアントに公開されている!?

2024/09/14に公開

先日、Next.jsのブログを読んでいたら、「Server Actionsの中でもバリデーションしてね」とあったので、注意喚起も兼ねて、その紹介ですmm

Server Actionsってなんやねんって方は、公式による説明か以下の記事がわかりやすかったので、まずはそちらからmm

https://zenn.dev/rio_dev/articles/eb69fae0557f20

Server Actions はクライアントに公開されている!?

ServerActionsで定義したすべての関数はエンドポイントが公開され、ユーザーは直接、エンドポイントから関数を実行できる状態になっています。

エンドポイントは特定されないように、ソースコードの場所をハッシュ化した値をもとに作成されているので、簡単にバレにくいようにはなってるっぽいです。
( !! ここの理解は曖昧なので、詳しい方いたら、教えてください 🙇‍♂️ !! )

Server Actions の中でもバリデーションをかけよう

ということで、 「フロント側でバリデーションしてるから、server actionsは任意の処理を実行するだけで良いよね〜」 はよくない!:no_good_tone1:
Server Actions の中でも、引数が適切な値なのか確認しましょう!:muscle:

公式が出してる例では、以下のようにidがnumber型か確かめています。TypeScriptで実装していても、実行される段階ではJavaScriptにトランスパイルされているので、型も確認しようねってことだと思います。

"use server";

export async function deletePost(id: number) {
  if (typeof id !== 'number') {
    throw new Error();
  }
  const user = await getCurrentUser();
  if (!canDeletePost(user, id)) {
    throw new Error();
  }
  ...
}

他にもありそうな例でいうと、ユーザーが処理を実行して良いユーザーかを認可するケース

"use server";

export async function updateAccount(data: hoge) {
  try {
    const user = await getCurrentUser()
    await updatedAccountGueard(user, data);

    await update();
  } catch (error) {
    throw Error()
  }
}

公式さんも以下のように言っていますので、Server Actions を使う際は、ちゃんと値を検証しましょうね。

The principle is that the argument list to Server Actions ("use server") must always be treated as hostile and the input has to be verified.

(↓翻訳 by DeepL↓)
原則としては、サーバーアクション("use server")の引数リストは常に敵対的なものとして扱われ、入力は検証されなければならない。

Discussion