FixVibe

// docs / baas security / supabase service role exposure

Supabase service role გასაღების გამოვლენა JavaScript-ში: რას ნიშნავს და როგორ ვიპოვოთ

Supabase service role გასაღები არის თქვენი მონაცემთა ბაზის უფროსი გასაღები. ნებისმიერი, ვინც მას ფლობს, გვერდს უვლის Row-Level Security-ს, შეუძლია წაიკითხოს ყოველი ცხრილის ყოველი სვეტი და შეუძლია ჩაწეროს ან წაშალოს ნებისმიერი, რასაც აირჩევს. ის გათვლილია იცხოვროს მხოლოდ სერვერის მხარის კოდში — არასოდეს ბრაუზერში. როცა AI-კოდირების ხელსაწყო მას აგზავნის JavaScript-ბანდლში, თქვენი მონაცემთა ბაზა, ფაქტობრივად, საჯაროა. ეს სტატია ხსნის JWT-ფორმას, რომელიც გამოვლენილ გასაღებს ამოიცნობს, სამ AI-ხელსაწყოს შაბლონს, რომელიც წარმოშობს გამოვლენას, რა გავაკეთოთ პირველ საათში გამოვლენის შემდეგ და როგორ დავასკანეროთ ის ავტომატურად მომხმარებლებზე ადრე.

რა არის service role გასაღები

Supabase გასცემს ორ განსხვავებულ გასაღებს ყოველი პროექტისთვის: anon-გასაღებს (ასევე ეწოდება გამოსაქვეყნებელი გასაღები ახალ პროექტებში) და service_role-გასაღებს. ორივე არის JSON Web Token, ხელმოწერილი თქვენი პროექტის JWT-საიდუმლოთი. განსხვავება არის role claim-ი, რომელიც ჩახედულია JWT-payload-ში — anon საჯარო გასაღებისთვის, service_role უფროსი გასაღებისთვის. PostgREST, Supabase Storage და Supabase Auth ყველა გადადის ყველაფრის გვერდს ავლის რეჟიმში, როცა ისინი ხედავენ service_role claim-ს.

გაშიფრეთ ნებისმიერი Supabase-გასაღები jwt.io-ზე და დააკვირდით payload-ს. service-role JWT-ის ფორმა შეუცდომელია:

service-role JWT-ის გაშიფრული payload (ნაჩვენებია როგორც სინტაქს-მონიშნული ბლოკი ქვემოთ).

json
{
  "iss": "supabase",
  "ref": "[project-ref]",
  "role": "service_role",
  "iat": 1700000000,
  "exp": 2000000000
}

ახალი Supabase-პროექტები გასცემენ secret-სტილის გასაღებებს sb_secret_ პრეფიქსით JWT-ის ნაცვლად. ქცევა იდენტურია — ნებისმიერი, რომელიც ატარებს sb_secret_-ს საჯარო ბანდლში, თანაბრად კატასტროფულია.

როგორ ჟონავენ AI-კოდირების ხელსაწყოები service role გასაღებს

ჩვენ ვნახეთ ერთი და იგივე სამი შაბლონი ათასობით vibe-coded აპებში. თითოეული იწყება დეველოპერით, რომელიც AI-ხელსაწყოს ეხმარება სთხოვს და მთავრდება service-key-ის ბანდლში მიწებებით.

შაბლონი 1: ერთი .env ფაილი NEXT_PUBLIC_ პრეფიქსით

დეველოპერი სთხოვს AI-ხელსაწყოს „დააყენე Supabase" და იღებს ერთ .env-ს ორივე გასაღებით. AI-ხელსაწყო — გაწვრთნილი კორპუსზე, სადაც გარემოს ცვლადების უმეტესობა გამოვლენილია NEXT_PUBLIC_*-ით — ორივეს NEXT_PUBLIC_-ით აპრეფიქსებს. Next.js ჩასვამს ნებისმიერს, რომელიც ემთხვევა ამ პრეფიქსს კლიენტის ბანდლში build-time-ზე. Vercel-ზე გაგზავნისას service-key არის main.[hash].js-ში.

შაბლონი 2: არასწორი გასაღები createClient გამოძახებაში

დეველოპერი ჩასვამს ორივე გასაღებს config.ts ფაილში, რომელიც AI-მ შექმნა და AI ცდომილებით ავსებს ბრაუზერის მხარის createClient() გამოძახებას process.env.SUPABASE_SERVICE_ROLE_KEY-ით. Build-ი ცვლადს იძენს და JWT ბანდლში ხვდება.

შაბლონი 3: service-role გასაღები ჩაკოდილია seed-სკრიპტებში

დეველოპერი სთხოვს AI-ხელსაწყოს დაწეროს სკრიპტი, რომელიც მონაცემთა ბაზას აყრიდრის. AI ჩაკოდავს service-role გასაღებს პირდაპირ ფაილში (გარემოდან წაკითხვის ნაცვლად), commit-ს უკეთებს ფაილს რეპოზიტორიაში და საჯარო GitHub-რეპო ან დეპლოიდი აპის /scripts/seed.js route ახლა გასცემს გასაღებს.

როგორ აღმოაჩენს FixVibe-ის ბანდლ-სკანი გამოვლენას

FixVibe-ის ბანდლ-საიდუმლოების შემოწმება ჩამოტვირთავს ყოველ JavaScript-ფაილს, რომელიც დეპლოიდი აპის მიერ არის მითითებული — entry chunks, lazy-loaded chunks, web workers, service workers — და ატარებს მათ დეტექტორში, რომელიც გაშიფრავს ნებისმიერს, რომელიც JWT-ფორმას ემთხვევა (eyJ[base64-header].eyJ[base64-payload].[signature]). თუ გაშიფრული payload შეიცავს "role": "service_role", სკანი მოახსენებს მას როგორც კრიტიკულ აღმოჩენას ფაილის გზასთან და ზუსტ ხაზთან ერთად, სადაც გასაღები ჩნდება. იგივე შემოწმება ასევე ემთხვევა უფრო ახალ sb_secret_* შაბლონს პრეფიქსით.

სკანი არასოდეს ავთენტიფიცირდება აღმოჩენილი გასაღებით. ის ამოიცნობს ფორმას და მოახსენებს გამოვლენას — გასაღების გამოყენება ექსპლუატაციის დასადასტურებლად იქნებოდა თქვენი მონაცემთა ბაზის უუფლებო წვდომა. დასაბუთება არის თვითონ JWT-payload-ში.

აღმოჩენილია — რა გავაკეთოთ პირველ საათში

გამოვლენილი service role გასაღები არის საგანგებო რეჟიმის სიტუაცია. ჩათვალეთ, რომ გასაღები გადათრეულია — თავდამსხმელები რეალურ დროში თვალს ადევნებენ საჯარო ბანდლებს. მიეპყარით მონაცემთა ბაზას, როგორც კომპრომეტირებულს, სანამ არ შეცვლით გასაღებს და არ ჩაატარებთ ბოლო აქტივობის აუდიტს.

  1. დაუყოვნებლივ შეცვალეთ გასაღები. Supabase Dashboard-ში გადადით Project Settings → API → Service role key → Reset-ში. ძველი გასაღები აუქმდება წამებში. ნებისმიერი სერვერის მხარის კოდი, რომელიც გასაღებს იყენებს, უნდა განახლდეს და თავიდან გაიშვას, სანამ ცვლა მოხდება.
  2. ჩაატარეთ ბოლო მონაცემთა ბაზის აქტივობის აუდიტი. გახსენით Database → Logs dashboard-ში. ფილტრი ბოლო 7 დღეზე. ეძებეთ უჩვეულო SELECT * მოთხოვნებს PII-ის შემცველი ცხრილების წინააღმდეგ, დიდ UPDATE- ან DELETE-დებულებებს და მოთხოვნებს IP-დან თქვენი ცნობილი ინფრასტრუქტურის გარეთ. Supabase ლოგავს x-real-ip header-ს ყოველ მოთხოვნაზე.
  3. შეამოწმეთ storage ობიექტები. ეწვიეთ Storage → Logs-ს და განიხილეთ ბოლო ფაილების ჩამოტვირთვები. გამოვლენილი service-role გასაღები იძლევა ყველაფრის გვერდს ავლის წვდომას პირად ბაკეტებზეც.
  4. ამოიღეთ გასაღები წყაროს კონტროლიდან. ცვლის შემდეგაც კი, JWT-ის დატოვება თქვენი git-ის ისტორიაში ნიშნავს, რომ ის აღმოჩენადია საჯარო რეპოში. გამოიყენეთ git filter-repo ან BFG Repo-Cleaner მისი ისტორიიდან გასაწმენდად, შემდეგ force-push (გააფრთხილეთ თანამშრომლები წინასწარ).
  5. თავიდან დაასკანერეთ გასწორების შემდეგ. გაუშვით ახალი FixVibe-სკანი თავიდან დეპლოიდი აპის წინააღმდეგ. ბანდლ-საიდუმლოების აღმოჩენა უნდა გაიწმინდოს. დარწმუნდით, რომ არც ერთი service_role JWT და არც ერთი sb_secret_* სტრიქონი არ რჩება არც ერთ chunk-ში.

გამოვლენის თავიდან აცილება

სტრუქტურული გასწორება არის სახელდების დისციპლინა პლუს ხელსაწყოს დონის დამცავი მექანიზმები:

  • არასოდეს მიამატოთ service-key-ს NEXT_PUBLIC_*, VITE_* ან რომელიმე სხვა ბანდლ-ჩამშენებელი პრეფიქსი. სახელდების კონვენცია არის საზღვარი — ყოველი ფრეიმვორქი მას პატივს სცემს.
  • დატოვეთ service-key მთლიანად დეველოპერის მანქანის .env-ის გარეთ. წაიკითხეთ ის საიდუმლოს მენეჯერიდან (Doppler, Infisical, Vercel-ის დაშიფრული env-ცვლადები) დეპლოიზე, არასოდეს commit გაუკეთოთ ლოკალურად.
  • <strong>Mark every Supabase client construction with explicit context.</strong> Files named <code>supabase/browser.ts</code> use the anon key; files named <code>supabase/server.ts</code> use the service-role key with <code>import 'server-only'</code> at the top. The <code>server-only</code> import causes a build error if a client component tries to consume the module.
  • <strong>Add a pre-commit hook that greps for JWT-shaped strings.</strong> <code>git diff --staged | grep -E 'eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+'</code> catches both anon and service tokens before they leave your machine.
  • დაამატეთ CI-კარიბჭე, რომელიც სკანერავს build-ის ოუტფუთს. next build-ის შემდეგ grep-ით ეძებეთ .next/static/chunks/ ოუტფუთში service_role სტრიქონს. დააფეილეთ build-ი, თუ რაიმე ემთხვევა.
bash
# Pre-commit hook: refuse any staged JWT-shaped string.
git diff --staged \
  | grep -E 'eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+' \
  && echo "JWT detected in staged changes — refusing commit" \
  && exit 1

# CI gate: fail the build if "service_role" shipped to the static bundle.
grep -RE 'service_role|sb_secret_' .next/static/chunks/ \
  && echo "Service-role credential leaked into bundle" \
  && exit 1

ხშირად დასმული შეკითხვები

რა სიჩქარით პოულობენ თავდამსხმელები გამოვლენილ Supabase service-role გასაღებებს?

საჯარო-ბანდლის სკანერები გადადგამენ ახალ დეპლოიმენტებს წუთებში. მკვლევრებმა დააფიქსირეს მუშა ექსპლოიტები ახალი Supabase-პროექტების წინააღმდეგ პირველი დეპლოის შემდეგ ერთ საათში. მიეპყარით ნებისმიერ service-role გამოვლენას, როგორც 60-წუთიან ფანჯარას, არა 60-დღიანს.

გასაღების ცვლა საკმარისია, თუ ვალდებული ვარ ვივარაუდო მონაცემების ექსფილტრაცია?

ცვლა აუქმებს გამოვლენილ გასაღებს, მაგრამ უკან ვერ აბრუნებს უკვე გადათრეულ მონაცემებს. თუ თქვენი ცხრილები შეიცავენ PII-ს, გადახდის მონაცემებს ან ნებისმიერ რეგულირებად მონაცემებს, შესაძლოა გქონდეთ შეტყობინების ვალდებულება GDPR-ის (72 საათი), CCPA-ის ან HIPAA-ის ფარგლებში. ჩაატარეთ ლოგების აუდიტი და გაიარეთ კონსულტაცია იურისტთან, თუ აუდიტი საეჭვო წვდომას აჩვენებს.

RLS-ს შეუძლია დამიცვას, თუ service-role გასაღები გამოვლინდა?

არა. Row-Level Security სრულად გვერდს უვლის service_role claim-ით. ეს არის გათვლილი — გასაღები არსებობს ზუსტად იმისთვის, რომ ბექენდის კოდი RLS-ს გვერდს უვლის ადმინ-ოპერაციებისთვის. შემარბილებელი ფაქტორი არის იმის უზრუნველყოფა, რომ გასაღები არასოდეს არ მიაღწევს კონტექსტს, სადაც თავდამსხმელს მისი წაკითხვა შეუძლია.

ეს ეხება ახალ Supabase publishable / secret გასაღების მოდელს (<code>sb_publishable_</code> / <code>sb_secret_</code>)?

კი — იდენტური რისკის კლასი. sb_secret_* გასაღები არის ახალი secret-გასაღების ფორმატი, რომელიც ცვლის service-role JWT-ს ახალი პროექტებისთვის. ნებისმიერი რამ, რომელიც ატარებს sb_secret_*-ს ბანდლში, ისეთივე კატასტროფულია, როგორც გამოვლენილი service-role JWT. FixVibe-ის ბანდლ-საიდუმლოების დეტექტორი ემთხვევა ორივე ფორმას.

რა შეიძლება ითქვას anon / publishable გასაღებზე — ის უსაფრთხოა ბანდლში?

კი, გათვლის მიხედვით. anon-გასაღები გათვლილია იცხოვროს ბრაუზერში და ის არის ის, რასაც ყოველი Supabase-ვებ-კლიენტი იყენებს. მისი უსაფრთხოება მთლიანად დამოკიდებულია იმაზე, RLS სწორად არის თუ არა კონფიგურირებული ყოველ საჯარო ცხრილზე. ნახეთ Supabase RLS სკანერი სტატია, თუ რა შესამოწმებელია.

შემდეგი ნაბიჯები

გაუშვით FixVibe-სკანი თქვენი პროდუქციის URL-ის წინააღმდეგ — ბანდლ-საიდუმლოების შემოწმება უფასოა, რეგისტრაციის გარეშე და მოახსენებს service_role-ის გამოვლენას წუთზე ნაკლებში. ეს დაუწყვილეთ Supabase RLS სკანერი სტატიას, რათა დაამოწმოთ, რომ RLS-ის ფენა თავის საქმეს აკეთებს, და Supabase storage-ბაკეტის უსაფრთხოების სია-ს, რათა ჩაკეტოთ ფაილებზე წვდომა. ფონური ცოდნისთვის, რატომ წარმოშობენ AI-ხელსაწყოები ამ გამოვლენის კლასს ასე საიმედოდ, წაიკითხეთ რატომ ტოვებენ AI-კოდირების ხელსაწყოები უსაფრთხოების ხარვეზებს.

// დაასკანერეთ თქვენი baas-ზედაპირი

იპოვეთ ღია ცხრილი მანამ, სანამ ვინმე სხვა აღმოაჩენს.

შეიყვანეთ პროდუქციის URL. FixVibe აღმოაჩენს BaaS-პროვაიდერებს, რომლებსაც თქვენი აპი ესაუბრება, ამოიცნობს მათ საჯარო endpoint-ებს და გაცნობებთ, რის წაკითხვა ან ჩაწერა შეუძლია არაავთენტიფიცირებულ კლიენტს. უფასოდ, დაყენების გარეშე, ბარათის გარეშე.

  • უფასო ტარიფი — 3 სკანი თვეში, რეგისტრაციის ბარათის გარეშე.
  • პასიური BaaS-fingerprinting — დომენის ვერიფიკაცია არ არის საჭირო.
  • Supabase, Firebase, Clerk, Auth0, Appwrite და სხვები.
  • AI-ფიქს-პრომპტი ყოველი აღმოჩენისთვის — ჩასვით უკან Cursor-ში / Claude Code-ში.
უფასო BaaS-სკანის გაშვება

რეგისტრაცია არ არის საჭირო

Supabase service role გასაღების გამოვლენა JavaScript-ში: რას ნიშნავს და როგორ ვიპოვოთ — Docs · FixVibe