// docs / security guides / hardening
AI कोडिंग टूल्स से बनी ऐप को कैसे सुरक्षित करें
आपके द्वारा Cursor, Claude Code, Lovable, Bolt, v0, Replit, या Windsurf के साथ बनाए गए ऐप्स के लिए चरण-दर-चरण सख्त मार्गदर्शिका। चार चरण: समझें कि AI- जेनरेट किए गए ऐप्स अलग-अलग क्यों विफल होते हैं, तत्काल कोडबेस ऑडिट चलाएं, तैनाती के समय सख्त करें, फिर निगरानी रखें। राययुक्त, कथात्मक, वास्तविक अंशों के साथ आप नकल कर सकते हैं।
AI- जेनरेट किए गए ऐप्स अलग-अलग तरीके से विफल क्यों होते हैं
वाइब-कोडित ऐप्स सुरक्षित हो सकते हैं। उन्हें अतिरिक्त ऑडिट पास की आवश्यकता है क्योंकि विफलता मोड संरचनात्मक हैं, लापरवाह नहीं:
- Cursor inlines hardcoded keys. आप Cursor को "प्रमाणीकरण त्रुटि को ठीक करने" के लिए कहते हैं और यह एक Supabase उदाहरण चिपका देता है जो एक सेवा-भूमिका क्लाइंट मानता है। कुंजी पृष्ठ घटक के शीर्ष पर समाप्त होती है। एनोन क्लाइंट और सर्विस क्लाइंट दोनों सह-अस्तित्व में हैं; दोनों जहाज.
- Claude Code defaults to permissive CORS. जेनरेटेड एक्सप्रेस / फास्टिफाई हैंडलर
cors({ origin: '*' })के साथ शिप करते हैं क्योंकि यह कार्यशील पूर्वावलोकन प्राप्त करने का सबसे तेज़ तरीका है। मिडलवेयर को कभी दूसरा पास नहीं मिलता। - Lovable and v0 skip the rules file. फायरस्टोर-समर्थित परियोजनाएं डेटा मॉडल उत्पन्न करती हैं लेकिन शायद ही कभी
firestore.rulesको स्पर्श करती हैं। परीक्षण-मोड नियम चुपचाप समाप्त हो जाते हैं और उपयोगकर्ता को बिना किसी चेतावनी के डेटाबेस को लॉक कर देते हैं। - Bolt skips RLS migrations. Bolt एक Supabase स्कीमा और एक CRUD सतह उत्पन्न करता है जो एनॉन कुंजी का उपयोग करता है।
ENABLE ROW LEVEL SECURITYकभी भी माइग्रेशन में प्रवेश नहीं करता। अनाम उपयोगकर्ता किसी भी पंक्ति को पढ़ या लिख सकते हैं। - Windsurf trusts unsigned IDs. जनरेट किया गया
GET /api/items/[id]स्वामित्व को सत्यापित किए बिना पैरामीटर पढ़ता है और पोस्टग्रेज पर प्रश्न पूछता है। पैटर्न इतना सामान्य है कि सक्रिय active.idor-walking जांच इसे एक ही स्कैन में सामने लाती है।
तत्काल ऑडिट: जोखिम पैटर्न के लिए अपना कोडबेस तैयार करें
इससे पहले कि आप किसी चीज़ को सख्त करें, जो पहले से ही टूटा हुआ है उसे ढूंढें। इन ग्रेप्स में से प्रत्येक को एक मिनट से कम समय लगता है:
रहस्य और प्रदाता कुंजियाँ
grep -RIn 'NEXT_PUBLIC_SUPABASE_SERVICE' src/
grep -RIn 'sk_live_\|pk_live_\|STRIPE_SECRET' src/
grep -RIn 'sk-ant-\|^sk-' src/ # Anthropic / OpenAI
grep -RIn 'AIza\|AKIA' src/ # Google / AWS
grep -RIn 'eyJh[A-Za-z0-9_-]\{20,\}' src/ # JWT-shaped stringsकिसी भी हिट को हटाने के साथ-साथ कुंजी घुमाने की आवश्यकता होती है। Proवाइडर डैशबोर्ड: Supabase → सेटिंग्स → API, Stripe → डेवलपर्स → API कुंजियाँ, एंथ्रोपिक / ओपनएआई कंसोल।
डेटाबेस अभिगम नियंत्रण
# Supabase migrations
grep -RIn 'CREATE TABLE public\.' supabase/migrations/
grep -RIn 'ENABLE ROW LEVEL SECURITY\|FORCE ROW LEVEL SECURITY' supabase/migrations/
# Firebase / Firestore
cat firestore.rules # confirm no `if true;` matchesप्रत्येक CREATE TABLE public.* को एक मेल खाने वाली ENABLE ROW LEVEL SECURITY और कम से कम एक पॉलिसी की आवश्यकता होती है। फायरस्टोर नियमों का दायरा request.auth.uid होना चाहिए।
प्रमाणीकरण और सत्र प्रबंधन
grep -RIn 'getSession()' src/ # should be getUser() server-side
grep -RIn 'localStorage\.\(set\|get\)Item.*token' src/
grep -RIn 'jwt.verify.*\(noVerify\|skipVerify\)' src/सर्वर-प्रदत्त मार्गों को supabase.auth.getUser() का उपयोग करना चाहिए - यह बैकएंड के साथ सत्यापित करता है। getSession() एक असत्यापित कुकी पढ़ता है। localStorage में टोकन पृष्ठ पर चलने वाली किसी भी स्क्रिप्ट तक पहुंच योग्य हैं।
हेडर और मिडलवेयर
# Confirm middleware location for src/ layouts
ls src/middleware.ts middleware.ts 2>&1
# Look for CSP and security headers
grep -RIn 'Content-Security-Policy\|Strict-Transport-Security' src/src/ लेआउट के साथ, केवल src/middleware.ts उठाया जाता है। यदि आपकी मिडलवेयर फ़ाइल प्रोजेक्ट रूट पर है, तो Next.js इसे चुपचाप अनदेखा कर देता है और आपका CSP / ऑथ-रिफ्रेश तर्क कभी नहीं चलता है।
तैनाती के समय सख्त होना
एक बार स्रोत साफ हो जाने पर, ऐप के उत्पादन तक पहुंचने के तरीके को लॉक कर दें।
चरण 1: अलग वातावरण
Vercel: तीन वातावरण - Proडक्शन (आपका उत्पाद डोमेन), पूर्वावलोकन (PR / स्टेजिंग परिनियोजन), विकास (स्थानीय)। प्रत्येक को अपना स्वयं का env-var सेट मिलता है। लाइव Stripe / एंथ्रोपिक / Supabase कुंजियाँ कभी पूर्वावलोकन तक नहीं पहुँचतीं; पूर्वावलोकन कुंजियाँ कभी भी Proडक्शन तक नहीं पहुँचतीं। शाखाएँ स्वचालित रूप से पूर्वावलोकन पर जोर देती हैं; main में मर्ज करें और Proडक्शन पर तैनात करें।
चरण 2: मिडलवेयर के माध्यम से सख्त CSP
प्रति-अनुरोध एक बार उत्पन्न करें, फिर इसे Content-Security-Policy में इंजेक्ट करें। जब आप x-nonce अनुरोध हेडर सेट करते हैं तो Next.js अपने स्वयं के स्क्रिप्ट टैग पर नॉन को स्वतः लागू करता है।
// src/middleware.ts
import { NextResponse, type NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const nonce = crypto.randomUUID().replace(/-/g, '');
const csp = [
`script-src 'nonce-${nonce}' 'strict-dynamic'`,
`style-src 'self' 'unsafe-inline'`,
`img-src 'self' data: https:`,
`connect-src 'self' https://*.supabase.co`,
`object-src 'none'`,
`base-uri 'self'`,
`frame-ancestors 'none'`,
].join('; ');
const requestHeaders = new Headers(request.headers);
requestHeaders.set('x-nonce', nonce);
const response = NextResponse.next({ request: { headers: requestHeaders } });
response.headers.set('Content-Security-Policy', csp);
response.headers.set('X-Content-Type-Options', 'nosniff');
response.headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
return response;
}
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};चरण 3: प्रत्येक सार्वजनिक टेबल पर RLS लागू करें
RLS डिफ़ॉल्ट रूप से सक्षम नहीं है और तालिका स्वामियों के लिए इसे तब तक लागू नहीं किया जाता जब तक आप इसे FORCE नहीं करते। प्रत्येक तालिका को प्रति भूमिका स्पष्ट नीतियों के साथ जोड़ें।
-- supabase/migrations/XXXX_rls.sql
alter table public.profiles enable row level security;
alter table public.profiles force row level security;
create policy "profiles: read own"
on public.profiles for select
using (auth.uid() = id);
create policy "profiles: update own"
on public.profiles for update
using (auth.uid() = id)
with check (auth.uid() = id);चरण 4: प्रत्येक API मार्ग पर केवल सर्वर प्रमाणीकरण
प्रत्येक राज्य बदलने वाला API मार्ग supabase.auth.getUser() के साथ कॉलर सर्वर-साइड को सत्यापित करता है। उपयोगकर्ता ऑब्जेक्ट user_id के लिए सत्य का स्रोत बन जाता है - इसे सेट करने के लिए अनुरोध निकाय पर कभी भरोसा न करें।
// src/app/api/items/route.ts
import { NextResponse, type NextRequest } from 'next/server';
import { createClient } from '@/lib/supabase/server';
export async function POST(request: NextRequest) {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) return NextResponse.json({ error: 'unauthorized' }, { status: 401 });
const body = await request.json();
const { data, error } = await supabase
.from('items')
.insert({ ...body, user_id: user.id }) // server-supplied, not from body
.select()
.single();
if (error) return NextResponse.json({ error: error.message }, { status: 400 });
return NextResponse.json(data);
}चरण 5: अपने विश्लेषण को रिवर्स-प्रॉक्सी करें
Proअपने स्वयं के डोमेन के माध्यम से विश्लेषण करने से विज्ञापन-अवरोधकों से बचा जा सकता है और आपके CSP connect-src 'self' को सीमित रखा जा सकता है। PostHog, प्लाज़िबल, उमामी, कस्टम इवेंट सिंक के लिए समान पैटर्न काम करता है।
// src/app/api/posthog/[...path]/route.ts
import { type NextRequest } from 'next/server';
const UPSTREAM = 'https://us.i.posthog.com';
export async function POST(req: NextRequest, { params }: { params: Promise<{ path: string[] }> }) {
const { path } = await params;
const url = `${UPSTREAM}/${path.join('/')}`;
return fetch(url, {
method: 'POST',
headers: { 'content-type': req.headers.get('content-type') ?? 'application/json' },
body: await req.text(),
});
}चरण 6: पोस्ट-ऑथ बाउंस पर ओपन-रीडायरेक्ट गार्ड
साइन-इन/साइन-अप प्रवाह आमतौर पर next क्वेरी पैरामीटर स्वीकार करते हैं। ऐसी किसी भी चीज़ को अस्वीकार करें जो समान-साइट पथ नहीं है - / से शुरू करें और कभी भी // (प्रोटोकॉल-सापेक्ष, उपयोगकर्ताओं को साइट से बाहर भेजता है) से शुरू करें।
function safeNext(raw: string | null): string {
if (!raw) return '/dashboard';
if (!raw.startsWith('/') || raw.startsWith('//')) return '/dashboard';
return raw;
}जारी: निगरानी और पुन: स्कैनिंग
बहाव प्रत्येक परिनियोजन पर होता है। सुरक्षा को एक लूप के रूप में मानें, न कि एक चेकलिस्ट के रूप में जिसे आप पूरा करते हैं।
अपना उत्पादन डोमेन सत्यापित करें
Dashboard → Domains → अपना उत्पाद डोमेन जोड़ें → DNS TXT या HTTP-फ़ाइल सत्यापन (एकल-चरण)। एक बार सत्यापित हो जाने पर, सक्रिय स्कैन उपलब्ध हो जाते हैं और निर्धारित पुन: स्कैन को सक्षम किया जा सकता है।
निष्क्रिय पुनः स्कैन शेड्यूल करें
प्रतिदिन Hobby पर, 3-घंटे Pro पर, प्रति घंटा Unlimited पर। यदि कोई नई खोज प्रकट होती है तो प्रत्येक रन आपको ईमेल करता है, और यदि आपने सदस्यता ले ली है तो scan.completed वेबहुक सक्रिय करता है।
# Or from CI, via the REST API:
curl -X POST https://fixvibe.app/api/v1/scans \
-H "authorization: Bearer $FIXVIBE_TOKEN" \
-H "content-type: application/json" \
-d '{"target":"https://your-app.com"}'API- सक्रिय स्कैन सक्षम करें (वैकल्पिक)
यदि आप स्वचालित सक्रिय जांच (SQLi / XSS / IDOR चलना / आदि) चाहते हैं, तो इसे डैशबोर्ड → डोमेन → API सक्रिय पर प्रति डोमेन चालू करें। प्राधिकरण टिकाऊ है, 90 दिन की समाप्ति, तुरंत रद्द करने योग्य। scan.active_api.first_used वेबहुक के साथ युग्मित करें ताकि सक्षम होने के बाद पहला स्वचालित सक्रिय स्कैन आपके अलर्ट तक पहुंच जाए।
अपने AI वर्कफ़्लो में निष्कर्षों को तार दें
Mint an API token at Account → API tokens, then configure the MCP server (/docs/mcp) in Claude Desktop / Cursor / Continue. Ask your agent: "Run a scan on staging and show me the highest-severity findings." The agent calls FixVibe, fetches the report, and renders categorized remediation guidance so code/config fixes become prompts and DNS/provider/manual fixes become operator steps.
लाइव खतरे का पता लगाना (Unlimited)
प्रमाणपत्र-पारदर्शिता लॉग आपके डोमेन के लिए जारी किए गए नए TLS प्रमाणपत्र को अलग करता है। DNS-रिकॉर्ड अंतर अनधिकृत परिवर्तनों को पकड़ता है। JS-बंडल गुप्त निगरानी उस समय सक्रिय हो जाती है जब कोई नई कुंजी भेजे गए बंडल तक पहुँचती है। थ्रेट-इंटेल फ़ीड (Spamhaus, URLhaus) आपके डोमेन को सूचीबद्ध होने पर रिपोर्ट करती है।
वास्तविक विफलता पैटर्न और उनके समाधान
हजारों AI- जेनरेट किए गए ऐप्स में उत्पादन स्कैन से पांच पैटर्न, प्रत्येक वास्तविक फिक्स के साथ:
- क्लाइंट घटक में सेवा-भूमिका कुंजी
Symptom:
baas.supabase-service-keyउत्पादन पर खोज URL। Cause: एक Cursor स्वत: पूर्णcreateClient(URL, SERVICE_ROLE_KEY)को रिएक्ट घटक में चिपकाया गया। Fix: सेवा क्लाइंट को शीर्ष परimport 'server-only'के साथsrc/lib/supabase/service.tsपर ले जाएं; क्लाइंट-साइड उपयोग के लिए एनोन कुंजी का उपयोग करके एक समानांतरsrc/lib/supabase/client.tsबनाएं; Supabase स्टूडियो के माध्यम से सेवा-भूमिका कुंजी घुमाएँ। - फ़ायरस्टोर नियम परीक्षण मोड में छोड़ दिए गए हैं
Symptom:
baas.firebase-rulesउच्च-गंभीरता वाली खोज। Cause: उत्पन्न नियम पढ़ेंallow read, write: if request.time < timestamp.date(2026, 6, 1);- एक समयबद्ध "सभी को अनुमति दें"। Fix: प्रत्येक नियम को प्रमाणित उपयोगकर्ता तक सीमित करें -match /users/{userId}/posts/{postId} { allow read, write: if request.auth.uid == userId; }- औरfirebase deploy --only firestore:rulesको पुनः तैनात करें। - अनुमेय CORS उत्पादन में जीवित रहना
Symptom:
active.corsउच्च-गंभीरता। Cause: जनरेट किया गया एक्सप्रेस मिडलवेयर:app.use(cors({ origin: '*' }))। Fix: अपने फ्रंटएंड मूल की अनुमति सूची:app.use(cors({ origin: ['https://your-app.com'], credentials: true }))। Next.js API मार्गों के लिए, प्रतिक्रिया में स्पष्ट रूप सेAccess-Control-Allow-Originसेट करें। - RLS सक्षम लेकिन बाध्य नहीं
Symptom: सक्रिय
baas.supabase-rlsरिपोर्ट करता है कि डैशबोर्ड में RLS सक्षम होने के बावजूद कोई भी भूमिका सार्वजनिक तालिका में लिखी जा सकती है। Cause:ENABLEबिनाFORCEके टेबल मालिक को छूट मिल जाती है - और माइग्रेशन मालिक के रूप में चलता है। Fix: माइग्रेशन मेंalter table public.items force row level security;जोड़ें। पुनः तैनाती. - अहस्ताक्षरित IDOR- चलने योग्य आईडी
Symptom:
active.idor-walkingरिपोर्ट करता है कि कोई भी उपयोगकर्ता किरायेदारों के बीच/api/items/1,/api/items/2, ... पढ़ सकता है। Cause: API हैंडलर पथ पैरामीटर पर भरोसा करता है और स्वामित्व विधेय के बिना पोस्टग्रेज पर प्रश्न पूछता है। Fix: प्रत्येक पढ़ी गई क्वेरी पर.eq('user_id', user.id)जोड़ें, या/api/users/[uid]/items/[id]के अंतर्गत हस्ताक्षरित यूआरएल/यूयूआईडी पर जाएं।
वाइब-कोड सुरक्षा लूप
लक्ष्य पूर्ण सुरक्षा नहीं है; यह कम लटकने वाले फल AI टूल को लगातार गायब कर रहा है ताकि आप तेजी से शिपिंग कर सकें।
- Generate fast - Cursor, Claude Code, Lovable, Bolt का उपयोग करें। बात तो यही है.
- Audit immediately - ऊपर दिए गए grep सेट को चलाएं, RLS जांचें, CSP सत्यापित करें, प्रमाणीकरण सीमा की समीक्षा करें।
- Harden at deploy - मिडलवेयर, पर्यावरण पृथक्करण, CSP नॉन्स, HSTS, सर्वर-केवल प्रमाणीकरण सत्यापन।
- Monitor - FixVibe निष्क्रिय दैनिक, सत्यापित डोमेन पर सक्रिय साप्ताहिक, स्लैक पर वेबहुक, Unlimited पर खतरे का पता लगाना।
- Fix fast — use FixVibe coding-agent prompts for code/config findings and operator steps for DNS, provider, secret-rotation, or manual-review findings. Re-deploy, re-scan, close the loop.
अगले चरण
DAST बनाम SAST पर वैचारिक पृष्ठभूमि के लिए और AI- जेनरेटेड ऐप्स को अपनी स्कैनिंग की आवश्यकता क्यों है, AI-generated code security scanning पढ़ें। त्वरित-संदर्भ प्री-शिप ऑडिट के लिए, vibe coding security checklist देखें।
