7Critique · critical
3Élevée · high
0Moyenne · medium
1Faible · low
11Total
Offre recommandée
- Pack Prêt pour la Prod (800–1500€)
- Déblocage Flash (150–300€)
Findings (11)
Critique · critical
1.Secret exposé au bundle via VITE_SUPABASE_SERVICE_ROLE_KEY
.env.example:3 · détecteur public-env-secret
VITE_SUPABASE_SERVICE_ROLE_KEY=your-se…[REDACTED]
- Remédiation
- Les variables
NEXT_PUBLIC_* / VITE_* / PUBLIC_* / REACT_APP_* sont copiées en clair dans le JavaScript livré au navigateur (nom de variable réservé aux secrets). Révoquer la clé, la renommer sans préfixe public, et faire l'appel depuis une route serveur / Edge Function qui la lit en variable d'environnement serveur. - Offre
- Pack Prêt pour la Prod (800–1500€)
Critique · critical
2.Secret exposé au bundle via VITE_RESEND_SECRET_KEY
.env.example:4 · détecteur public-env-secret
VITE_RESEND_SECRET_KEY=your-…[REDACTED]
- Remédiation
- Les variables
NEXT_PUBLIC_* / VITE_* / PUBLIC_* / REACT_APP_* sont copiées en clair dans le JavaScript livré au navigateur (nom de variable réservé aux secrets). Révoquer la clé, la renommer sans préfixe public, et faire l'appel depuis une route serveur / Edge Function qui la lit en variable d'environnement serveur. - Offre
- Pack Prêt pour la Prod (800–1500€)
Critique · critical
3.Clé Supabase service_role utilisée côté client
src/integrations/supabase/client.ts:5 · détecteur service-role-client
const SUPABASE_ADMIN_KEY = import.meta.env.VITE_SUPABASE_SERVICE_ROLE_KEY;
- Remédiation
- La clé service_role contourne toute la RLS : elle ne doit jamais atteindre le navigateur. Côté front, utiliser uniquement la clé anon/publishable ; déplacer les opérations admin dans une Edge Function qui lit
SUPABASE_SERVICE_ROLE_KEY depuis ses secrets, puis régénérer la clé exposée. - Offre
- Pack Prêt pour la Prod (800–1500€)
Critique · critical
4.Secret exposé au bundle via VITE_RESEND_SECRET_KEY
src/lib/email.ts:1 · détecteur public-env-secret
const RESEND_KEY = import.meta.env.VITE_RESEND_SECRET_KEY;
- Remédiation
- Les variables
NEXT_PUBLIC_* / VITE_* / PUBLIC_* / REACT_APP_* sont copiées en clair dans le JavaScript livré au navigateur (nom de variable réservé aux secrets). Révoquer la clé, la renommer sans préfixe public, et faire l'appel depuis une route serveur / Edge Function qui la lit en variable d'environnement serveur. - Offre
- Pack Prêt pour la Prod (800–1500€)
Critique · critical
5.Clé secrète Stripe exposée dans le bundle front
src/lib/stripe.ts:1 · détecteur secrets
const STRIPE_SECRET_KEY = 'sk_li…[REDACTED]';
- Remédiation
- Révoquer et régénérer la clé immédiatement (elle est publique). Déplacer l'appel dans une Edge Function / route serveur et lire la clé depuis une variable d'environnement serveur (jamais préfixée VITE_/NEXT_PUBLIC_).
- Offre
- Pack Prêt pour la Prod (800–1500€)
Critique · critical
6.Table sans RLS : public.invoices
supabase/migrations/20250110120000_init.sql:15 · détecteur supabase-rls
create table public.invoices (
- Remédiation
- Ajouter une migration
ALTER TABLE public.invoices ENABLE ROW LEVEL SECURITY; puis des policies explicites (ex. USING (auth.uid() = user_id)). Sans RLS, la clé anon publique donne lecture/écriture totale sur la table. - Offre
- Pack Prêt pour la Prod (800–1500€)
Critique · critical
7.Table sans RLS : public.subscriptions
supabase/migrations/20250110120000_init.sql:25 · détecteur supabase-rls
create table public.subscriptions (
- Remédiation
- Ajouter une migration
ALTER TABLE public.subscriptions ENABLE ROW LEVEL SECURITY; puis des policies explicites (ex. USING (auth.uid() = user_id)). Sans RLS, la clé anon publique donne lecture/écriture totale sur la table. - Offre
- Pack Prêt pour la Prod (800–1500€)
Élevée · high
8.Edge Function « stripe-webhook » publique sans authentification (verify_jwt = false)
supabase/config.toml:4 · détecteur edge-fn-no-auth
[functions.stripe-webhook] verify_jwt = false
- Remédiation
- Vérifier l'appelant en tête de handler :
supabase.auth.getUser(token) avec le header Authorization (puis filtrer sur user.id), ou une signature / un secret partagé pour un webhook. Réserver verify_jwt = false aux webhooks signés et n'utiliser le client service_role qu'après ce contrôle. - Offre
- Pack Prêt pour la Prod (800–1500€)
Élevée · high
9.Webhook Stripe sans vérification de signature
supabase/functions/stripe-webhook/index.ts:8 · détecteur stripe-webhook
const event = (await req.json()) as Stripe.Event;
- Remédiation
- Lire le body brut (
express.raw() / await req.text()) et appeler stripe.webhooks.constructEvent(rawBody, sig, STRIPE_WEBHOOK_SECRET) (ou constructEventAsync en Edge/Deno) avant tout traitement ; rejeter en 400 si la signature est invalide. Sinon n'importe qui peut forger un checkout.session.completed. - Offre
- Déblocage Flash (150–300€)
Élevée · high
10.Policy RLS permissive (true) sur public.profiles
supabase/migrations/20250110120000_init.sql:12 · détecteur supabase-rls
create policy "Profiles are viewable by everyone" on public.profiles
- Remédiation
- Remplacer
USING (true) / WITH CHECK (true) par une condition liée à l'utilisateur, ex. USING (auth.uid() = user_id), et restreindre la policy au rôle authenticated et à la commande nécessaire (FOR SELECT/INSERT…). - Offre
- Pack Prêt pour la Prod (800–1500€)
Faible · low
11.Body de requête utilisé sans validation de schéma
supabase/functions/create-invoice/index.ts:17 · détecteur zod-missing
const body = await req.json();
- Remédiation
- Valider le body avec un schéma avant usage :
const input = Schema.safeParse(await req.json()) (zod / valibot), renvoyer 400 si !input.success, puis n'utiliser que input.data. Évite les champs inattendus (ex. role, user_id) injectés par un client malveillant. - Offre
- Déblocage Flash (150–300€)