보안 가이드 2026.03.11 · 조회 7752

Next.js 보안 설정 가이드 (2026)

Next.js 프로젝트에 적용할 보안 설정 총정리. next.config.js 헤더, 환경변수 분리, API Route 인증까지.

S
보안 전문 기업 SENTRIX 레드팀
해킹대회 수상 · 보안 실무 10년 · 실전 진단 경험을 바탕으로 작성합니다.
웹사이트를 운영하고 있다면
보안 헤더·인증서·공개 노출부터 무료로 점검하세요. 결과 링크는 이메일로 받습니다. 로그인 이후 권한·업무 로직은 별도 검증이 필요합니다.

다음 화면에서 이메일과 점검 권한을 확인합니다. 회원가입·카드 없이 무료 요약을 받고, 상세 리포트는 선택 구매합니다.

Next.js 기본 설정만으로는 보안이 부족하다

Vercel에 Next.js를 배포하면 HTTPS는 자동으로 된다. 거기서 만족하고 끝내는 경우가 많다. 하지만 보안 헤더, 환경변수 관리, API 인증, 이 세 가지는 직접 챙겨야 한다.

next.config.js 보안 헤더 설정

// next.config.js
const securityHeaders = [
    {
        key: 'X-DNS-Prefetch-Control',
        value: 'on'
    },
    {
        key: 'Strict-Transport-Security',
        value: 'max-age=63072000; includeSubDomains; preload'
    },
    {
        key: 'X-Frame-Options',
        value: 'DENY'
    },
    {
        key: 'X-Content-Type-Options',
        value: 'nosniff'
    },
    {
        key: 'Referrer-Policy',
        value: 'strict-origin-when-cross-origin'
    },
    {
        key: 'Permissions-Policy',
        value: 'camera=(), microphone=(), geolocation=()'
    },
    {
        key: 'Content-Security-Policy',
        value: "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline';"
    }
];

module.exports = {
    async headers() {
        return [
            {
                source: '/:path*',
                headers: securityHeaders,
            },
        ];
    },
};

환경변수 NEXT_PUBLIC 분리

Next.js에서 NEXT_PUBLIC_ 접두사가 붙은 환경변수는 클라이언트 번들에 포함된다. 즉, 누구나 소스코드에서 볼 수 있다.

# .env.local

# 클라이언트에 노출됨 (anon key, 공개 URL만 여기에)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...

# 서버에서만 사용 (절대 NEXT_PUBLIC_ 붙이지 않기)
SUPABASE_SERVICE_ROLE_KEY=eyJ...
OPENAI_API_KEY=sk-...
DATABASE_URL=postgresql://...

API Route 인증 처리

// pages/api/user/profile.js
import { getServerSession } from "next-auth/next";
import { authOptions } from "./auth/[...nextauth]";

export default async function handler(req, res) {
    // 반드시 세션 확인 먼저
    const session = await getServerSession(req, res, authOptions);
    if (!session) {
        return res.status(401).json({ error: 'Unauthorized' });
    }

    // 인증된 사용자만 아래 코드 실행
    const userId = session.user.id;
    // ... 로직
}

Middleware로 전역 인증 처리

// middleware.js
import { withAuth } from "next-auth/middleware";

export default withAuth({
    callbacks: {
        authorized: ({ token }) => !!token,
    },
});

export const config = {
    matcher: ['/dashboard/:path*', '/api/admin/:path*'],
};

설정 완료 후 배포하고 나서 CodeScan으로 헤더가 제대로 적용됐는지 확인하는 걸 루틴으로 만들어두면 좋다.

내 사이트도 점검해보세요

URL 입력, 결과 링크는 메일로 받는 무료 점검. 회원가입·카드 불필요.

AI 코딩 보안 체크리스트 받기

AI 코딩 보안 체크리스트(PDF)를 무료로 받아보세요.

배포·설정을 바꾼 뒤에는 같은 주소를 다시 점검하세요. 수정 후 재점검 순서와 일정 저장 · 자동 점검이 필요하면 Continuous의 범위와 체험 조건을 확인하세요.
이런 글을 계속 받아보려면 뉴스레터 구독 · RSS 피드