Next.js Server Actions मध्ये use-server फाईलमध्ये एक्सपोर्ट केलेली प्रत्येक फंक्शन एका सार्वजनिक HTTP एंडपॉइंट (endpoint) म्हणून आपोआप उपलब्ध होते, ज्याला एक युनिक आयडेंटिफायर (unique identifier) दिला जातो ज्याचा वापर क्लायंट फंक्शन कॉल करण्यासाठी करतो. बटण, लिंक किंवा इतर कोणताही UI घटक रेंडर झाला असो वा नसो, तो एंडपॉइंट अस्तित्वात असतो, याचा अर्थ असा की ज्याला तो आयडेंटिफायर सापडेल तो कोणीही थेट फंक्शन कॉल करू शकतो.

फ्रेमवर्कची रचना Server Actions ला सामान्य हेल्पर फंक्शन्सप्रमाणे मानत असली, तरी रनटाइमला ते पोहोचण्यायोग्य (reachable) URLs बनतात. ज्या डेव्हलपर्सना असे वाटले की UI हा एकमेव गेटकीपर आहे, त्यांच्यासाठी हे एक अदृश्य अटॅक सरफेस (attack surface) तयार करते ज्याचा वापर एका तयार केलेल्या (crafted) रिक्वेस्टद्वारे केला जाऊ शकतो.

Server Actions सुरक्षित का वाटत होते

डेव्हलपर्सना त्यांच्या कंपोनेंट्सच्या अगदी जवळ सर्व्हर-साइड कोड लिहिण्याची सुविधा देण्यासाठी आणि वेगळ्या API रूट्सचा (API routes) क्लिष्टपणा टाळण्यासाठी Server Actions आणले गेले होते. एक सामान्य वापर असा दिसतो:

<form action={deleteInvoice}>
  <button type="submit">Delete</button>
</form>

deleteInvoice ट्रिगर करण्याचा फॉर्म हा एकमेव दृश्य मार्ग असल्याने, अनेक डेव्हलपर्स अनधिकृत वापरकर्त्यांसाठी बटण लपवतात, TypeScript सिग्नेचरमुळे चुकीचा डेटा (malformed data) रोखला जाईल असे मानतात आणि फंक्शन फक्त सर्व्हर-ओन्ली मॉड्यूलमध्ये आहे यावर अवलंबून राहतात. यापैकी कोणतीही गृहितके वास्तविक संरक्षण प्रदान करत नाहीत.

छुपे एक्सपोजर (The hidden exposure)

जेव्हा एखाद्या फाईलमध्ये “use server” असते, तेव्हा Next.js प्रत्येक एक्सपोर्ट केलेल्या फंक्शनला अशा एंडपॉइंटमध्ये कंपाईल करते:

POST /_next/data/<build-id>/<page>.json?__rsc=<action-id>

<action-id> हा एक स्टेबल हॅश (stable hash) आहे जो क्लायंट बंडलमध्ये एम्बेड केलेला असतो. अटॅकर तो खालील प्रकारे मिळवू शकतो:

  • पेजच्या नेटवर्क ट्रॅफिकचे निरीक्षण करून (Inspecting the page’s network traffic).
  • बंडल केलेल्या JavaScript मधून वाचून (The ID is a plain string).
  • जर प्रोजेक्टमध्ये काही ठराविक पॅटर्न असतील, तर नेमिंग कन्व्हेन्शन्सच्या (naming conventions) आधारे अंदाज लावून.

एकदा आयडेंटिफायर समजला की, कोणत्याही टूलमधून—cURL, Postman किंवा एखादा घातक स्क्रिप्ट—रिक्वेस्ट पाठवता येते, ज्यामुळे सर्व UI-लेव्हल चेक बायपास होतात.

तीन ठोस धोके (Three concrete risks)

धोका याचे महत्त्व काय
UI चेक प्रभावी नाहीत बटण किंवा लिंक लपवल्याने मूळ एंडपॉइंट डिलीट होत नाही. एंडपॉइंट पोहोचण्यायोग्य राहतो, अगदी एखाद्या लपविलेल्या ॲडमिन पेजप्रमाणे जे सर्व्हरवर अजूनही अस्तित्वात असते.
TypeScript रनटाइम सुरक्षा देत नाही कोड रन होताना टाइप्स (types) काढून टाकले जातात. deleteInvoice(id: number) म्हणून घोषित केलेले फंक्शन एखादा मोठा स्ट्रिंग, ॲरे किंवा अगदी घातक JSON देखील स्वीकारू शकते, ज्यामुळे लॉजिक एरर्स किंवा इंजेक्शन अटॅक्स होऊ शकतात.
डिफॉल्ट ऑथेंटिकेशन किंवा ऑथोरायझेशन नाही Server Actions हे स्थानिक हेल्परसारखे दिसतात, त्यामुळे डेव्हलपर्स अनेकदा सेशन चेक, CSRF प्रोटेक्शन किंवा रो-लेव्हल परमिशन चेक जोडण्यास विसरतात, जे पारंपारिक API रूट्समध्ये मानक असतात.

Server Action सुरक्षित कसे करावे

  1. कॉलरचे ऑथेंटिकेशन करा (Authenticate the caller) – कोणताही बिझनेस लॉजिक रन होण्यापूर्वी वैध सेशन किंवा टोकन अस्तित्वात आहे याची खात्री करा.
  2. पेलोड व्हॅलिडेट करा (Validate the payload) – रनटाइमला डेटा टाइप्स आणि व्हॅल्यू कन्स्ट्रेंट्स लागू करण्यासाठी स्कीमा लायब्ररी (उदा. Zod, Yup) वापरा.
  3. ऑपरेशनला ऑथोराईज करा (Authorize the operation) – “वापरकर्ता लॉग इन आहे का?” या पलीकडे जाऊन, वापरकर्ता ज्या विशिष्ट रेकॉर्डमध्ये बदल किंवा डिलीट करण्याचा प्रयत्न करत आहे, त्याचा मालक तोच आहे याची खात्री करा.

एक किमान उदाहरण:

'use server';
import { getSession } from '@/auth';
import { z } from 'zod';
import { db } from '@/db';

const DeleteInvoiceSchema = z.object({
  id: z.number().int().positive(),
});

export async function deleteInvoice(formData: FormData) {
  const session = await getSession();
  if (!session) throw new Error('Unauthenticated');

  const parsed = DeleteInvoiceSchema.safeParse({
    id: Number(formData.get('id')),
  });
  if (!parsed.success) throw new Error('Invalid input');

  const invoice = await db.invoice.findUnique({ where: { id: parsed.data.id } });
  if (!invoice || invoice.ownerId !== session.userId) {
    throw new Error('Unauthorized');
  }

  await db.invoice.delete({ where: { id: invoice.id } });
}

हा कोड स्पष्टपणे ऑथेंटिकेशन तपासतो, येणारा id व्हॅलिडेट करतो आणि डिलीट करण्यापूर्वी लॉग-इन केलेला वापरकर्ता खरोखरच त्या इनव्हॉइसचा मालक आहे याची खात्री करतो.

इतर सूक्ष्म Next.js अडचणी (Other subtle Next.js pitfalls)

समस्या लक्षण उपाय
NEXT_PUBLIC_ env vars NEXT_PUBLIC_ ने सुरू होणारी कोणतीही गोष्ट क्लायंटमध्ये बंडल केली जाते, ज्यामुळे सीक्रेट्स (secrets) उघड होतात. सीक्रेट्स साध्या env vars मध्ये ठेवा, त्यांना कधीही NEXT_PUBLIC_ ने प्रीफिक्स करू नका.
Open redirects redirect क्वेरी पॅरामीटर स्वीकारणे आणि तो थेट जोडणे (concatenating) वापरकर्त्यांना //evil.com वर पाठवू शकते. व्हाईटलिस्टच्या विरुद्ध टार्गेट व्हॅलिडेट करा किंवा सेम-ओरिजिन चेक लागू करा.
Server-Side Request Forgery (SSRF) वापरकर्त्याने दिलेली URL फेच केल्यामुळे अटॅकर अंतर्गत सेवा किंवा क्लाउड मेटाडेटा एंडपॉइंट्सपर्यंत पोहोचू शकतात. होस्टनेम्सना अलाउ-लिस्ट (Allow-list) करा, खाजगी IP रेंज ब्लॉक करा आणि टाइमआउट सेट करा.
dangerouslySetInnerHTML सॅनिटायझेशनशिवाय वापरकर्त्याने दिलेला HTML रेंडर केल्याने XSS होऊ शकते. DOMPurify सारखी लायब्ररी वापरा किंवा कच्चा (raw) HTML वापरणे टाळा.

या पॅटर्नसाठी स्वयंचलितपणे स्कॅनिंग करणे

स्टॅटिक-ॲनालिसिस टूल्स वरील धोकादायक रचनांना फ्लॅग करू शकतात. Semgrep हा एक हलका पर्याय आहे, जो वेगाने चालतो आणि CI पाइपलाइन्समध्ये समाकलित (integrate) केला जाऊ शकतो:

npx --yes semgrep --config https://raw.githubusercontent.com/catidegla/stacksec/main/rules .

या रूल सेटमध्ये एक्सपोर्ट केलेल्या सर्व्हर फंक्शन्स, NEXT_PUBLIC_ चा गैरवापर, ओपन रिडायरेक्ट्स, SSRF पॅटर्न आणि असुरक्षित HTML इन्सर्शनसाठी तपासणी समाविष्ट आहे.

पुढे काय पाहावे

  • Framework updates – Next.js च्या रिलीजेसवर लक्ष ठेवा; टीम इन-बिल्ट authentication hooks आणू शकते किंवा जनरेट केलेल्या endpoints ला sandbox करू शकते.
  • Community tooling – येथे वर्णन केलेल्या सुरक्षा उपायांचे (safeguards) ऑटोमेशन करण्यासाठी नवीन ESLint plugins आणि Next.js-विशिष्ट Semgrep rules समोर येत आहेत.
  • Real-world incidents – जसे अधिक प्रोजेक्ट्स Server Actions चा वापर करतील, तसे प्रत्यक्ष व्यवहारात असलेला धोका दर्शविणारे उघड झालेले exploits तपासा. एखादी breach होण्यापूर्वी लवकर शोध घेतल्यास अंतर्गत security reviews साठी मदत होऊ शकते.

निष्कर्ष: Next.js Server Action हे खाजगी helper नाही; तुम्ही ते export करताच ते एक सार्वजनिक HTTP endpoint बनते. ते इतर कोणत्याही API route प्रमाणे हाताळा—authenticate, validate आणि authorize करा—अन्यथा UI च्या जवळ server code लिहिण्याची सोय झपाट्याने security liability ठरू शकते.