// docs / security guides / hardening
AI कोडिंग टूल्स से बनी ऐप को कैसे सुरक्षित करें
आपके द्वारा Cursor, Claude Code, Lovable, Bolt, v0, Replit, या Windsurf के साथ बनाए गए ऐप्स के लिए चरण-दर-चरण सख्त मार्गदर्शिका। चार चरण: समझें कि AI- जेनरेट किए गए ऐप्स अलग-अलग क्यों विफल होते हैं, तत्काल कोडबेस ऑडिट चलाएं, तैनाती के समय सख्त करें, फिर निगरानी रखें। राययुक्त, कथात्मक, वास्तविक अंशों के साथ आप नकल कर सकते हैं।
AI- जेनरेट किए गए ऐप्स अलग-अलग तरीके से विफल क्यों होते हैं
वाइब-कोडित ऐप्स सुरक्षित हो सकते हैं। उन्हें अतिरिक्त ऑडिट पास की आवश्यकता है क्योंकि विफलता मोड संरचनात्मक हैं, लापरवाह नहीं:
- Assistants inline hardcoded keys. You ask for a fix to an auth error and get a pasted Supabase example that assumes a service-role client. The key ends up at the top of a page component. Both the anon client and the service client coexist; both ship.
- Generated servers default to permissive CORS. Generated Express / Fastify handlers often ship with
cors({ origin: '*' })because that's the fastest way to get a working preview. The middleware never gets a second pass. - Rules files get skipped. Firestore-backed projects generate the data model but rarely touch
firestore.rules. Test-mode rules let anyone read and overwrite data until someone replaces them. - RLS never enters the migration. A generated Supabase schema and CRUD surface use the anon key, but
ENABLE ROW LEVEL SECURITYnever enters the migration. Anonymous users can read or write any row. - Handlers trust IDs. A generated
GET /api/items/[id]reads the param and queries Postgres without verifying ownership. Active scans on a verified domain test for this (IDOR / BOLA).
तत्काल ऑडिट: जोखिम पैटर्न के लिए अपना कोडबेस तैयार करें
इससे पहले कि आप किसी चीज़ को सख्त करें, जो पहले से ही टूटा हुआ है उसे ढूंढें। इन ग्रेप्स में से प्रत्येक को एक मिनट से कम समय लगता है:
रहस्य और प्रदाता कुंजियाँ
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 isn't enabled by default on tables you create in SQL or migrations. Enable it on every exposed table and pair each one with explicit policies per role — that is what stops the anon and authenticated roles. FORCE only makes the table owner obey RLS too.
-- 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 → add your production domain → DNS TXT or HTTP-file verification. Active scans require Hobby or above; scheduled re-scans require Pro or Unlimited.
निष्क्रिय पुनः स्कैन शेड्यूल करें
Scheduled re-scans are available on Pro and Unlimited for verified domains. Free and Hobby scans are manual. Scheduled scans use your plan allowance. Configure completion email preferences and a scan.completed webhook if needed.
# 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 वर्कफ़्लो में निष्कर्षों को तार दें
On Hobby or above, create an API token at Account → API tokens and configure the MCP server (/docs/mcp) in your coding tool. Ask your agent to run an authorized scan and inspect the highest-severity findings. Code fixes can use remediation prompts; provider and DNS fixes may need manual operator steps.
लाइव खतरे का पता लगाना (Unlimited)
Periodic certificate-transparency, DNS, JS-bundle, and threat-intelligence checks report observed changes on supported signals. Alerts depend on successful polling and source availability; they do not establish continuous or complete security coverage.
वास्तविक विफलता पैटर्न और उनके समाधान
Five common patterns in AI-generated apps, each with the actual fix:
- क्लाइंट घटक में सेवा-भूमिका कुंजी
Symptom: FixVibe reports an exposed Supabase service-role key on the production URL. Cause: an autocomplete pasted
createClient(URL, SERVICE_ROLE_KEY)into a React component. Fix: move the service client tosrc/lib/supabase/service.tswithimport 'server-only'at the top; create a parallelsrc/lib/supabase/client.tsusing the anon key for client-side use; rotate the service-role key via Supabase Studio. - फ़ायरस्टोर नियम परीक्षण मोड में छोड़ दिए गए हैं
Symptom: a high-severity open Firebase rules finding. Cause: generated rules read
allow read, write: if request.time < timestamp.date(2026, 6, 1);— a time-bounded "allow all". Fix: scope each rule to the authenticated user —match /users/{userId}/posts/{postId} { allow read, write: if request.auth.uid == userId; }— and re-deployfirebase deploy --only firestore:rules. - अनुमेय CORS उत्पादन में जीवित रहना
Symptom: a high-severity CORS misconfiguration finding. Cause: generated Express middleware:
app.use(cors({ origin: '*' })). Fix: allowlist your frontend origin:app.use(cors({ origin: ['https://your-app.com'], credentials: true })). For Next.js API routes, setAccess-Control-Allow-Originexplicitly in the response. - RLS सक्षम लेकिन बाध्य नहीं
Symptom: FixVibe reports that anonymous visitors can read a public table even though RLS looks enabled in the dashboard. Cause: RLS is on, but a policy such as
USING (true)lets theanonrole through, or the migration that tightened it never ran in production. Fix: replace the permissive policy with one scoped toauth.uid(), apply the migration, and re-scan. - अहस्ताक्षरित IDOR- चलने योग्य आईडी
Symptom: an active scan on your verified domain reports that one user can read another user's records at
/api/items/1,/api/items/2, ... Cause: the API handler trusts the path param and queries Postgres without an ownership predicate. Fix: add.eq('user_id', user.id)on every read query, or move to signed URLs / UUIDs scoped under/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 देखें।
