nextjs보안서버액션
서버 액션 보안 체크리스트 — use server는 public API다
✨ AI 요약
긴 글, 핵심만 먼저 — 이 글을 3줄로 정리해드려요.
조회 26
Next.js 서버 액션은 편하다. 너무 편해서 위험하다. "use server"를 붙이는 순간 그 함수는 네트워크에 노출된 엔드포인트가 된다는 사실을 잊기 쉽다.
1. 모든 액션의 첫 줄은 인증이다
액션은 버튼에 연결돼 있어도, 버튼 없이도 호출할 수 있다. 액션 ID만 알면 curl로도 부른다.
"use server";
export async function deletePost(postId: string) {
const me = await currentUser();
if (!me) throw new Error("unauthorized"); // ← 이 줄이 없으면 사고
const post = await prisma.post.findFirst({
where: { id: postId, authorId: me.id }, // ← 소유권까지
});
if (!post) throw new Error("not found");
...
}
"UI에서 내 글에만 버튼이 보이니까"는 보안이 아니다. 인증(누구냐) + 인가(네 것이냐) 둘 다 액션 안에서 다시 확인해야 한다.
2. 입력은 전부 불신
formData, 인자 전부 클라이언트가 조작 가능하다. 특히 id류 — 남의 리소스 id를 넣는 IDOR가 서버 액션 사고의 단골이다. where 절에 항상 소유자 조건을 함께 건다.
3. 반환값도 노출이다
액션이 반환하는 객체는 직렬화돼 클라이언트로 간다. User 객체를 통째로 반환하면 passwordHash도 함께 간다. 필요한 필드만 골라 반환하자.
4. redirect 함정 두 가지
- redirect()는 throw 기반이라 try/catch로 감싸면 삼켜진다 — catch에서 rethrow 필요
- 리다이렉트 URL은 HTTP 헤더에 실리므로 한글 등 non-ASCII는 encodeURIComponent 필수 (안 하면 500)
5. 뮤테이션 뒤 revalidate
보안은 아니지만 짝으로 기억하자. revalidatePath 없으면 "됐는데 화면은 그대로"가 된다.
요약: 서버 액션은 이름만 함수지 실체는 POST 엔드포인트다. API 라우트에 하던 검증을 하나도 빼놓지 말 것.