من سه اشتباه پرهزینه در احراز هویت با Next.js 16 مرتکب شدم
من در تنظیمات matcher فایل proxy.ts در سه پروژه مختلف اشتباه کردم.
بدترین بخش؟ هیچ خطایی وجود نداشت. هیچ هشداری نبود. هیچ لاگی ثبت نشد. همه چیز عالی به نظر میرسید تا اینکه حفرههای امنیتی ظاهر شدند.
در Next.js 16، فایل middleware.ts به proxy.ts تغییر یافته است. این فقط یک تغییر نام ساده نیست؛ بلکه یک تغییر بنیادین در نحوه مدیریت درخواستهاست.
در اینجا آنچه باید بدانید تا سیستم احراز هویت خود را از کار نیندازید، آورده شده است.
قوانین جدید Middleware گیجکننده بود. توسعهدهندگان از آن برای فراخوانی دیتابیس و منطقهای سنگین استفاده میکردند. این وظیفه آن نیست.
proxy در مرز شبکه قرار میگیرد و درخواستها را قبل از رسیدن به مسیرهای (routes) شما رهگیری میکند.
- بهصورت پیشفرض روی Node.js اجرا میشود، نه Edge runtime.
- پشتیبانی کامل از crypto را دریافت میکنید.
- میتوانید از هر کتابخانه استاندارد JWT بدون نیاز به راهکارهای جانبی استفاده کنید.
شکست بیصدا
اگر Next.js را بدون استفاده از یک codemod ارتقا دهید، ممکن است فایل قدیمی middleware.ts در پروژه شما باقی بماند. این فایل از بررسیهای TypeScript عبور میکند و بدون مشکل کامپایل میشود.
اما هیچ کاری انجام نخواهد داد.
ریدایرکتهای شما اجرا نمیشوند. احراز هویت شما کار نخواهد کرد. اپلیکیشن شما بهسادگی و بهصورت بیصدا از لایه امنیتی عبور میکند.
این سه مورد را بهصورت دستی بررسی کنید:
- مطمئن شوید
proxy.tsدر ریشه (root) پروژه شما قرار دارد. - مطمئن شوید تابع اکسپورت شده
proxyنام دارد، نهmiddleware. - فایل قدیمی
middleware.tsرا بهطور کامل حذف کنید.
تلهی matcher
بیشتر تنظیمات احراز هویت در پیکربندی matcher دچار مشکل میشوند. اگر فایلهای استاتیک را استثنا نکنید، proxy روی هر فایل CSS و JS اجرا میشود. این کار باعث ایجاد حلقههای ریدایرکت بینهایت روی داراییها (assets) میشود.
از یک negative lookahead برای استثنا کردن موارد زیر استفاده کنید:
_next/static_next/image- faviconها و sitemapها
- پسوندهای تصاویر (png, jpg, svg)
هشدار: فقط به Headerها اعتماد نکنید اینجا همان جایی است که من آسیب دیدم.
proxy هدرهایی مانند x-user-id را روی درخواست تنظیم میکند. Server Componentهای شما اینها را از طریق headers() میخوانند.
اگر در matcher شما شکافی وجود داشته باشد، کاربر میتواند هدر x-user-id خودش را ارسال کند. Server Component نمیتواند تفاوت بین هدر تنظیمشده توسط proxy و هدر ارسالشده توسط کلاینت را تشخیص دهد.
یک مهاجم میتواند در یک مسیر (route) که با matcher مطابقت ندارد، یک user ID جعلی ارسال کند. آنها ممکن است دادهها را نبینند، اما میتوانند به مجوزهایی دسترسی پیدا کنند که نباید داشته باشند.
راه حل:
proxy دروازه سریع شماست. کارهای سنگین را در لایه edge انجام میدهد.
اما شما باید JWT را دوباره در داخل Server Componentهای خود تأیید کنید.
- پروکسی اکثر عوامل مخرب را به سرعت متوقف میکند.
- بررسی Server Component در صورت شکست matcher، این شکاف را پر میکند.
افزونگی یعنی امنیت.