Next.js Server Actions, use-server ఫైల్‌లో ఎగుమతి చేయబడిన (exported) ప్రతి ఫంక్షన్‌ను ఒక పబ్లిక్ HTTP ఎండ్‌పాయింట్‌గా ఆటోమేటిక్‌గా మారుస్తాయి. క్లయింట్ ఆ ఫంక్షన్‌ను పిలవడానికి (invoke చేయడానికి) ఒక ప్రత్యేకమైన ఐడెంటిఫైయర్‌ను ఇది కేటాయిస్తుంది. బటన్, లింక్ లేదా మరే ఇతర UI ఎలిమెంట్ రెండర్ చేయబడినా లేకపోయినా ఆ ఎండ్‌పాయింట్ అందుబాటులో ఉంటుంది, అంటే ఆ ఐడెంటిఫైయర్‌ను కనుగొన్న ఎవరైనా నేరుగా ఆ ఫంక్షన్‌ను కాల్ చేయవచ్చు.

ఈ ఫ్రేమ్‌వర్క్ డిజైన్ Server Actionsను సాధారణ హెల్పర్ ఫంక్షన్‌ల వలె పరిగణిస్తుంది, కానీ రన్‌టైమ్‌లో అవి అందుబాటులో ఉండే URLలుగా మారుతాయి. UI మాత్రమే ఒక గేట్‌కీపర్‌గా పనిచేస్తుందని భావించే డెవలపర్‌లకు, ఇది ఒకే ఒక్క క్రాఫ్టెడ్ రిక్వెస్ట్‌తో దుర్వినియోగం చేయగల ఒక అదృశ్య అటాక్ సర్ఫేస్‌ను (attack surface) సృష్టిస్తుంది.

Server Actions సురక్షితంగా ఎందుకు అనిపించాయి

ప్రత్యేకమైన API రూట్‌ల యొక్క బోయిలర్‌ప్లేట్ (boilerplate) పనిని నివారించడానికి, డెవలపర్‌లు తమ కాంపోనెంట్‌ల పక్కనే సర్వర్-సైడ్ కోడ్‌ను వ్రాయడానికి వీలుగా Server Actions పరిచయం చేయబడ్డాయి. సాధారణ వాడకం ఇలా ఉంటుంది:

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

deleteInvoiceను ట్రిగ్గర్ చేయడానికి ఫారమ్ మాత్రమే కనిపించే మార్గం కాబట్టి, చాలా మంది డెవలపర్‌లు అనధికారిక వినియోగదారుల కోసం బటన్‌ను దాచిపెడతారు, TypeScript సిగ్నేచర్‌లు తప్పుడు డేటాను అడ్డుకుంటాయని అనుకుంటారు మరియు ఆ ఫంక్షన్ సర్వర్-ఓన్లీ మాడ్యూల్‌లో ఉందని నమ్ముతారు. ఈ ఊహలలో ఏదీ నిజమైన రక్షణను అందించదు.

దాగి ఉన్న ఎక్స్‌పోజర్

ఒక ఫైల్‌లో “use server” ఉన్నప్పుడు, Next.js ప్రతి ఎగుమతి చేయబడిన ఫంక్షన్‌ను ఈ క్రింది విధంగా ఒక ఎండ్‌పాయింట్‌గా కంపైల్ చేస్తుంది:

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

<action-id> అనేది క్లయింట్ బండిల్‌లో ఉండే ఒక స్టేబుల్ హాష్. ఒక అటాకర్ దీనిని ఈ క్రింది విధంగా పొందవచ్చు:

  • పేజీ యొక్క నెట్‌వర్క్ ట్రాఫిక్‌ను పరిశీలించడం ద్వారా.
  • బండిల్ చేయబడిన JavaScriptను చదవడం ద్వారా (ID అనేది ఒక సాధారణ స్ట్రింగ్).
  • ప్రాజెక్ట్ ఊహించదగిన ప్యాటర్న్‌లను అనుసరిస్తుంటే, నామింగ్ కన్వెన్షన్ల ఆధారంగా ఊహించడం ద్వారా.

ఒకసారి ID తెలిసిన తర్వాత, cURL, Postman లేదా ఏదైనా మాలీషియస్ స్క్రిప్ట్ వంటి ఏ సాధనం నుండి అయినా రిక్వెస్ట్‌ను పంపవచ్చు, దీనివల్ల UI-లెవల్ తనిఖీలను బైపాస్ చేయవచ్చు.

మూడు స్పష్టమైన రిస్క్‌లు

రిస్క్ ఇది ఎందుకు ముఖ్యం
UI తనిఖీలు ప్రభావవంతంగా ఉండవు బటన్ లేదా లింక్‌ను దాచడం వల్ల అంతర్లీన ఎండ్‌పాయింట్ తొలగించబడదు. సర్వర్‌లో ఇంకా ఉన్న ఒక దాగి ఉన్న అడ్మిన్ పేజీ వలె, ఆ ఎండ్‌పాయింట్ అందుబాటులో ఉంటుంది.
TypeScript రన్‌టైమ్ భద్రతను అందించదు కోడ్ రన్ అవుతున్నప్పుడు టైప్స్ తొలగించబడతాయి. deleteInvoice(id: number) అని ప్రకటించిన ఫంక్షన్‌కు భారీ స్ట్రింగ్, అర్రే లేదా మాలీషియస్ JSON కూడా అందుอาจ, ఇది లాజిక్ లోపాలకు లేదా ఇంజెక్షన్ దాడులకు దారితీస్తుంది.
డిఫాల్ట్ అథెంటికేషన్ లేదా అథరైజేషన్ ఉండదు Server Actions స్థానిక హెల్పర్ల వలె కనిపిస్తాయి, కాబట్టి డెవలపర్‌లు సాంప్రదాయ API రూట్‌లలో ఉండే సెషన్ తనిఖీలు, CSRF రక్షణ లేదా రో-లెవల్ పర్మిషన్ తనిఖీలను జోడించడం మర్చిపోతుంటారు.

Server Actionను ఎలా సురక్షితం చేయాలి

  1. కాల్ చేసే వ్యక్తిని అథెంటికేట్ చేయండి – ఏదైనా బిజినెస్ లాజిక్ రన్ కావడానికి ముందు చెల్లుబాటు అయ్యే సెషన్ లేదా టోకెన్ ఉందో లేదో ధృవీకరించండి.
  2. పేలోడ్‌ను వాలిడేట్ చేయండి – రన్‌టైమ్‌లో డేటా రకాలు మరియు విలువ పరిమితులను అమలు చేయడానికి ఒక స్కీమా లైబ్రరీని (ఉదా: Zod, Yup) ఉపయోగించండి.
  3. ఆపరేషన్‌ను అథరైజ్ చేయండి – “యూజర్ లాగిన్ అయ్యారా?” అని చూడటమే కాకుండా, వారు సవరించడానికి లేదా తొలగించడానికి ప్రయత్నిస్తున్న నిర్దిష్ట రికార్డు వారికి చెందినదేనా అని నిర్ధారించుకోండి.

ఒక చిన్న ఉదాహరణ:

'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 లోపాలు

సమస్య లక్షణం పరిష్కారం
NEXT_PUBLIC_ env vars NEXT_PUBLIC_ తో మొదలయ్యే ఏదైనా క్లయింట్‌లోకి బండిల్ చేయబడుతుంది, దీనివల్ల సీక్రెట్‌లు బయటపడతాయి. సీక్రెట్‌లను సాధారణ env వేరియబుల్స్‌లో ఉంచండి, వాటికి ఎప్పుడూ NEXT_PUBLIC_ ప్రిఫిక్స్ ఇవ్వకండి.
Open redirects redirect క్వెరీ పారామీటర్‌ను స్వీకరించి, దానిని నేరుగా కలుపుకోవడం వల్ల వినియోగదారులు //evil.comకి వెళ్లే అవకాశం ఉంది. వైట్‌లిస్ట్ ద్వారా టార్గెట్‌ను వాలిడేట్ చేయండి లేదా సేమ్-ఓరిజిన్ తనిఖీలను అమలు చేయండి.
Server-Side Request Forgery (SSRF) యూజర్ అందించిన URLను ఫెచ్ చేయడం వల్ల అటాకర్లు అంతర్గత సర్వీసులను లేదా క్లౌడ్ మెటాడేటా ఎండ్‌పాయింట్‌లను చేరుకోవచ్చు. హోస్ట్‌నేమ్‌లను వైట్‌లిస్ట్ చేయండి, ప్రైవేట్ IP రేంజ్‌లను బ్లాక్ చేయండి మరియు టైమ్‌అవుట్‌లను సెట్ చేయండి.
dangerouslySetInnerHTML శానిటైజేషన్ (sanitisation) లేకుండా యూజర్ అందించిన HTMLని రెండర్ చేయడం వల్ల XSS దాడులు జరిగే అవకాశం ఉంది. DOMPurify వంటి లైబ్రరీని ఉపయోగించండి లేదా నేరుగా HTMLని వాడకండి.

ఈ ప్యాటర్న్‌లను ఆటోమేటిక్‌గా స్కాన్ చేయడం

పైన పేర్కొన్న రిస్క్‌తో కూడిన నిర్మాణాలను స్టాటిక్-అనాలిసిస్ టూల్స్ గుర్తించగలవు. Semgrep అనేది ఒక తేలికపాటి ఎంపిక, ఇది వేగంగా రన్ అవుతుంది మరియు CI పైప్‌లైన్‌లలో ఇంటిగ్రేట్ చేయవచ్చు:

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

ఈ రూల్ సెట్‌లో ఎగుమతి చేయబడిన సర్వర్ ఫంక్షన్‌లు, NEXT_PUBLIC_ దుర్వినియోగం, ఓపెన్ రీడైరెక్ట్‌లు, SSRF ప్యాటర్న్‌లు మరియు అన్‌సేఫ్ HTML ఇన్సర్షన్ కోసం తనిఖీలు ఉంటాయి.

తదుపరి ఏమి గమనించాలి

  • ఫ్రేమ్‌వర్క్ అప్‌డేట్‌లు – Next.js విడుదలలను గమనిస్తూ ఉండండి; బృందం built-in authentication hooksను ప్రవేశపెట్టవచ్చు లేదా జనరేట్ చేయబడిన endpointsను sandbox చేయవచ్చు.
  • కమ్యూనిటీ టూలింగ్ – ఇక్కడ వివరించిన రక్షణ చర్యలను ఆటోమేట్ చేయడానికి కొత్త ESLint plugins మరియు Next.js-నిర్దిష్ట Semgrep rules వస్తున్నాయి.
  • వాస్తవ ప్రపంచ సంఘటనలు – ఎక్కువ ప్రాజెక్ట్‌లు Server Actionsను స్వీకరించే కొద్దీ, ఆచరణలో ఉన్న రిస్క్‌ను వివరించే బహిర్గతమైన exploits పట్ల జాగ్రత్తగా ఉండండి. ఏదైనా బ్రీచ్ జరగకముందే, ముందస్తు గుర్తింపు అంతర్గత సెక్యూరిటీ రివ్యూలకు ఉపయోగపడుతుంది.

ముగింపు (Takeaway): Next.js Server Action అనేది ఒక ప్రైవేట్ హెల్పర్ కాదు; మీరు దానిని export చేసిన క్షణమే అది ఒక పబ్లిక్ HTTP endpoint అవుతుంది. దీనిని మరే ఇతర API route లాగైనా పరిగణించండి—authenticate చేయండి, validate చేయండి మరియు authorize చేయండి—లేకపోతే, UI పక్కనే server code వ్రాయడం వల్ల కలిగే సౌలభ్యం త్వరగా ఒక security liabilityగా మారవచ్చు.