امنیت در Next.js ( دونستن این نکته ها ضروریه !! )

اگه توی دنیای فرانت اند مشغول کار هستی یا تازه وارد دنیای React و Next.js شدی، احتمال زیاد تمرکزت بیشتر روی طراحی، کامپوننت ساختن، ریسپانسیو کردن و چیزای جذاب دیگست 🙂 ولی یه چیز خیلی مهم هست که نباید دستکم بگیریش: امنیت!
حالا شاید بگی: ” بابا من که فقط فرانت اندم، امنیت مال بک اندیاست! “
اما واقعیت اینه که توی Next.js، چون کد فرانت و بک با هم ترکیب شده، مسئولیت امنیت تا حد زیادی هم به دوش توئه.
امنیت یعنی چی اصلاً؟
امنیت یعنی اینکه کاری کنیم هکرها نتونن اطلاعات کاربران رو بدزدن، سایت رو خراب کنن، یا به جاهایی دسترسی پیدا کنن که نباید.
بیاید مرحله به مرحله با مثال های ساده بررسی کنیم که چطوری میتونیم یه پروژه Next.js رو امن تر کنیم.
۱. گرفتن اطلاعات از URL ؟
فرض کن یه صفحه داری که از URL اطلاعات میگیره. مثلاً:/product?itemId=123
توی Next.js راحت میتونی اون مقدار رو با searchParams یا params بگیری.
ولی مشکل چیه؟ این ورودی از سمت کاربر میاد و قابل اعتمــــــاد نیست!
 راه حل:
 راه حل:
حتماً باید ورودی هایی که از کاربر میگیری رو بررسی و اعتبارسنجی (Validate) کنی. مثلاً با کتابخونه هایی مثل Zod یا [Yup]
				
					import { z } from 'zod';
const schema = z.object({
  itemId: z.string().regex(/^\d+$/),
});
const result = schema.safeParse({ itemId: searchParams.get("itemId") });
if (!result.success) {
  throw new Error("Invalid itemId");
}
 
				
			
		عملیات حساس؟ فقط توی سرور!
توی Next.js میتونی یه فرم داشته باشی که اطلاعاتی رو به سرور بفرسته، مثلاً فرم تماس با ما یا پرداخت. برای این کار از Server Actions استفاده میکنیم.
 اما یه نکته مهم:
 اما یه نکته مهم:
Server Actions یه جور تابع سمت سروره. فقط چون توی فایل server تعریفش کردی دلیل نمیشه که امنیت خودش حل شده باشه. 
باید خودت چک کنی یسری مسائل امنیتی رو:
- کاربر لاگین هست یا نه؟ 
- ورودی ها درسته؟ 
- مجاز هست که اون کار رو بکنه یا نه؟ 
				
					"use server";
import { z } from "zod";
export async function createPost(formData: FormData) {
  const schema = z.object({
    title: z.string().min(1),
    content: z.string().min(10),
  });
  const data = Object.fromEntries(formData.entries());
  const result = schema.safeParse(data);
  if (!result.success) {
    throw new Error("Invalid form data");
  }
  // کاربر رو چک کن
  const user = await getUserSession();
  if (!user) throw new Error("Not authenticated");
  // حالا دیتا رو تو دیتابیس ذخیره کن
}
 
				
			
		۳. جلوی حملات معروف رو بگیر
XSS ( حمله ی تزریق کد در مرورگر )
XSS یعنی هکر یه کدی (معمولاً JavaScript) به سایت تزریق میکنه و مثلاً اطلاعات لاگین کاربرا رو میدزده.
 اشتباه رایج :
				
					
			
		اگه userContent توسط کاربر نوشته شده باشه، اینجا دیگه فاجعست!
 راه حل: از sanitize مثل DOMPurify استفاده کن. البته اگر SSR هست، sanitize باید سمت سرور هم انجام بشه.
CSRF ( جعل درخواست از طرف کاربر )
CSRF یعنی یه سایت دیگه کاری میکنه که انگار کاربر خودش یه فرم توی سایت تو پر کرده، در حالی که خودش خبر نداره!
✅ راه حل: استفاده از توکن CSRF (مثلاً با @edge-runtime/csrf یا csrf) اگر فرم از دامنه ی دیگه ای ارسال میشه، به همراه SameSite=Strict یا Lax برای کوکی ها.
مسیر های امن با Route Handlers
اگه یه فایل توی app/api/user/route.ts ساختی، یادت نره که اونجا هم باید امنیت رو رعایت کنی:
				
					export async function POST(req: Request) {
  const session = await getSession();
  if (!session) return new Response("Unauthorized", { status: 401 });
  const body = await req.json();
  // validate body
}
 
				
			
		۴. اطلاعات حساس؟ نه توی فرانت اند!
Next.js این قابلیت رو داره که یه سری از متغیر های محیطی رو توی فرانت اند هم بفرسته، مثلاً NEXT_PUBLIC_API_URL.
ولی یادت باشه: هیچوقت کلید API یا رمز یا هر اطلاعات حساسی رو توی فرانت نذار!
چون هر کاربر با DevTools میتونه ببینتشون.
 راه حل: فقط توی بک اند یا سرور استفاده کن. (یعنی توی فایل هایی که با 
"use server" شروع میشن یا API routes.)
۵. وابستگی ها رو جدی بگیر!
بعضی وقتا یه پکیجی که نصب میکنی، ممکنه خودش آسیب پذیر باشه. مثلاً یه باگ امنیتی داشته باشه.
✅ راه حل:
- مرتباً - npm auditبزن.
- یا از ابزار هایی مثل Dependabot استفاده کن. 
- از پکیج های مشکوک یا ناشناس با تعداد دانلود پایین پرهیز کن. 
6. احراز هویت (Authentication) به روش درست!
احراز هویت یعنی اینکه بفهمیم کاربر کیه. توی Next.js میتونی با ابزارهایی مثل:
- یا حتی دستی با JWT 
کار احراز هویت رو انجام بدی.
چرا مهمه؟
چون خیلی از عملیات ها باید فقط برای کاربرای لاگین شده باشه. مثلاً :
- فرستادن فرم 
- آپدیت پروفایل 
- دیدن سفارشات 
 راه درست استفاده در Server Action:
 راه درست استفاده در Server Action:
								
				
					"use server";
import { getServerSession } from "next-auth";
export async function updateProfile(formData: FormData) {
  const session = await getServerSession();
  if (!session) {
    throw new Error("Not logged in");
  }
  // عملیات امن بعد از لاگین بودن
}
 
				
			
		7. Authorization یا مجوز دسترسی
حالا فرض کن کاربر لاگینه ولی میخواد به اطلاعات یه کاربر دیگه دسترسی پیدا کنه.
این همون جاییه که فقط Auth کافی نیست. باید بررسی کنی آیا کاربر اجازه انجام اون کار رو داره یا نه؟
				
					if (session.user.id !== post.authorId) {
  throw new Error("You can't edit this post");
}
 
				
			
		8. کوکی امن = سایت امن تر!
بعضی وقتا اطلاعاتی مثل توکن ورود کاربر رو داخل کوکی ذخیره میکنیم. اما این کوکی باید به درستی تنظیم بشه:
 مشکل رایج:
 مشکل رایج:
کوکی به صورت پیشفرض برای همه ی جاها قابل دسترسه، حتی از طریق جاوااسکریپت داخل مرورگر.
 راهحل:
 راهحل:
حتماً کوکی رو با این ویژگی ها ذخیره کن: ( این فقط در فایل هایی با use server یا API route استفاده بشه )
				
					cookies().set("token", tokenValue, {
  httpOnly: true, // قابل دسترسی از جاوااسکریپت نیست
  secure: true,   // فقط در HTTPS
  sameSite: "strict", // برای جلوگیری از CSRF
});
 
				
			
		9. امنیت فایل ها و عکس ها (Upload)
فرض کن کاربر اجازه داره عکس آپلود کنه. اگه فایلی که آپلود میشه رو بررسی نکنی، هکر میتونه یه فایل اجرایی، اسکریپت مخرب یا حتی shell آپلود کنه !!
 باید بررسی کنی:
 باید بررسی کنی:
- نوع فایل ( - image/png,- image/jpeg, …)
- حجم فایل 
- نام فایل 
- حذف متادیتای مخرب 
برای اینکار میتونی از کتابخونه هایی مثل:
- multer
- sharp(برای تغییر سایز و پاک سازی فایل)
10. CSP – Content Security Policy
این یکی شاید یه کم تخصصی تر باشه، ولی بهترین خط دفاعی در برابر XSS هست.
 چی کار میکنه؟
 چی کار میکنه؟
CSP مشخص میکنه مرورگر اجازه داره چه اسکریپت هایی رو اجرا کنه. مثلاً فقط از دامنه ی خودت.
تنظیم توی Next.js:
				
					// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: "/(.*)",
        headers: [
          {
            key: "Content-Security-Policy",
            value: "default-src 'self'; script-src 'self'; object-src 'none';",
          },
        ],
      },
    ];
  },
};
 
				
			
		این پالیسی برای سایتهایی که از CDN یا font یا iframe استفاده میکنن، ممکنه باعث بلاک شدن بشه. مثلاً اگر از Google Fonts یا Stripe یا تصاویر خارجی استفاده بشه، باید به صورت زیر باشه:
				
					default-src 'self';
script-src 'self' https://js.stripe.com;
img-src 'self' data:;
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
font-src https://fonts.gstatic.com;
frame-src https://js.stripe.com;
 
				
			
		یه چک لیست سریع برای یادآوری امنیت در نکست جی اس!
- ورودی هایی مثل - paramsو- searchParamsاعتبارسنجی شدن؟ (با Zod یا Yup)
- فقط اطلاعات امن از سمت کاربر استفاده شده؟ 
- ورودی ها قبل از استفاده در کوئری دیتابیس چک شدن؟ 
- از - "use server"به درستی استفاده شده؟
- ورودی های فرم validate شدن؟ 
- هویت کاربر قبل از عملیات چک شده؟ 
- مجوز (authorization) بررسی شده؟ مثلا فقط نویسنده بتونه پست خودش رو ویرایش کنه؟ 
- از - dangerouslySetInnerHTMLاستفاده نشده یا همراه با sanitize (مثل DOMPurify) استفاده شده؟
- Content Security Policy (CSP) تنظیم شده؟ 
- همه درخواستهای POST دارای کوکی با - SameSite=Strictیا- Laxهستن؟
- برای API های حساس، Origin چک شده؟ 
- از ابزار امن برای لاگین مثل NextAuth.js یا Clerk استفاده شده؟ 
- توکن کاربر با کوکی HttpOnly ذخیره شده؟ 
- کاربر قبل از انجام عملیات حساس چک شده؟ 
- بررسی شده که فقط افراد مجاز به منابع خاص دسترسی دارن؟ 
- نقش های کاربر (مثلاً admin, user) به درستی کنترل شدن؟ 
- هیچ کلید API یا secret توی فرانت (با - NEXT_PUBLIC_) منتشر نشده؟
- فایل های - .envدر- .gitignoreهستن؟
- فقط فرمت های خاص (مثلاً فقط عکس) مجاز هستن؟ 
- حجم فایل محدود شده؟ 
- فایل قبل از ذخیره با Sharp یا ابزار مشابه پاک سازی شده؟ 
- کوکی ها با ویژگی های - HttpOnly,- Secure,- SameSiteست شدن؟
- کوکی ها فقط برای مسیر های لازم استفاده میشن؟ 
- npm auditمرتب اجرا شده؟
- پکیج ها با نسخه های امن آپدیت شدن؟ 
- پکیج های ناشناخته یا بدون maintain حذف شدن؟ 
- لاگ ها اطلاعات حساس نشون نمیدن؟ 
- صفحات admin یا private فقط بعد از لاگین قابل دسترس هستن؟ 
- مسیرهای API محافظت شده هستن؟ 
- فایل هایی مثل - .env,- .DS_Store,- node_modulesروی هاست یا ریپو نیفتادن؟
جمع بندی
امنیت توی پروژه های Next.js فقط وظیفه ی بک اند نیست. چون Next.js یه فریمورک فول استکه، پس فرانت اند کارا هم باید حواسشون باشه.
با چند قدم ساده مثل اعتبارسنجی، چک کردن لاگین کاربر، و جلوگیری از تزریق کد میتونی یه سایت حرفه ای و امن بسازی.
امنیت تو Next.js مثل بستن کمربند ایمنی تو رانندگیه: شاید اولش یکم سخت باشه، ولی یه روزی نجاتت میده 🙂
درباره احمد احمدنژاد
من یه برنامه نویس و توسعه دهنده وب هستم که عاشق دنیای صفر و یکم❤️
نوشتههای بیشتر از احمد احمدنژاد






دیدگاهتان را بنویسید