Skip to content
Back to skills

Otopcy Securite

BSecurity

Use when writing or reviewing anything touching authentication, sessions, cookies, CSRF, rate limiting, roles and permissions, security headers or CSP, file uploads, or the browser HTTP client. Also use when asked to "secure", "harden" or review an endpoint. Covers enumeration-resistant signup, double-submit CSRF and its one documented exception, two-tier rate limiting, role precedence, origin-list CSP (and why not a nonce), magic-byte upload validation.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 1, 2026
databasesreactapisecurity

Works with

  • cli
  • api

Security analysis

B75/100
  • criticalAccesses sensitive system or user directories

Pro shows the line behind each finding and how to fix it

Scanned October 1, 2026

npx -y skills add Giovannyengamba/Otopcy-Softstart --skill otopcy-securite --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Otopcy Securite?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Otopcy Securite
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/giovannyengamba-otopcy-securite/badge)](https://www.skillsdirectory.com/skills/giovannyengamba-otopcy-securite)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: otopcy-securite
description: Use when writing or reviewing anything touching authentication, sessions, cookies, CSRF, rate limiting, roles and permissions, security headers or CSP, file uploads, or the browser HTTP client. Also use when asked to "secure", "harden" or review an endpoint. Covers enumeration-resistant signup, double-submit CSRF and its one documented exception, two-tier rate limiting, role precedence, origin-list CSP (and why not a nonce), magic-byte upload validation.
---

# Sécurité — Otopcy SoftStart

Par Giovanny Engamba (giovannyengamba.com) · Otopcy (otopcy.com).

## Les quatre failles à chercher en premier

1. Clé d'administration (« service ») côté client — contourne tout.
2. Règles d'accès à la base jamais activées (resté en mode prototype).
3. Contrôle d'accès fait en React sans équivalent serveur.
4. `.env` commité au premier push — et resté dans l'historique.

## Sessions

| Jeton | Durée | Portée |
|---|---|---|
| Accès | 15 min | tous chemins |
| Rafraîchissement | 7 j | **`/api/auth` uniquement** |
| CSRF | 7 j | tous chemins |

Cookies `httpOnly` + `Secure` (prod) + `SameSite=Lax`, préfixés par projet.

**L'inscription ne révèle rien** : réponse identique que l'e-mail existe ou
non, **aucun cookie émis à l'inscription** (ils viennent de la vérification
d'e-mail). Compare contre un haché factice quand l'utilisateur n'existe pas
— sinon le **temps de réponse** trahit l'existence du compte.

## CSRF

Double soumission : cookie `<prefix>-csrf` + en-tête `x-csrf-token`. Un
tiers peut faire envoyer le cookie, pas le lire.

```ts
const csrf = verifyCsrf(req);
if (csrf) return csrf;   // en tête de CHAQUE POST/PUT/PATCH/DELETE
```

Exception possible — un acheteur sans compte n'a pas de cookie CSRF :
vérifier **seulement si une session existe**, parce que le CSRF ne défend
que l'autorité ambiante d'une session. Compenser par une limitation de
débit. **Toute exception s'écrit dans le code, avec sa raison et sa date.**

## Limitation de débit

Deux étages : **par IP** (bruit, balayages) et **par e-mail** (attaque
ciblée, qui passe l'étage IP en changeant d'adresse).
Connexion 10/15 min · inscription 5/h · mot de passe oublié 3/h.
Repli mémoire = **par instance** : insuffisant en production.

## Rôles

`USER < ADMIN < SUPERADMIN` · `MEMBER < ADMIN < OWNER`.

```ts
const auth = await requireAdmin(req);
if (auth instanceof NextResponse) return auth;
```

Seul un SUPERADMIN change un rôle · on refuse de rétrograder le **dernier**
SUPERADMIN · un non-membre d'organisation reçoit **404, pas 403** (un 403
confirme l'existence).

L'interface s'adosse à des **capacités** (`devis:delete`), pas à des rôles.
Ça reste de l'affichage : le serveur revérifie toujours.

## En-têtes et CSP

Dans `next.config.ts`, pas le middleware — pour que le cache les serve sans
réveiller de fonction.

**Liste d'origines, pas nonce** : un nonce force chaque page par une
fonction et tue la mise en cache du site entier, alors que `'unsafe-inline'`
reste souvent nécessaire de toute façon.

Ce qui compte vraiment : `object-src 'none'`, `base-uri 'self'`,
`form-action 'self'`, `frame-ancestors 'none'`, `script-src <liste>`.

⚠️ **Gestionnaire de balises** : c'est un script qui en **injecte d'autres**.
Une campagne publicitaire tirera un domaine absent de ton dépôt. Non listé
⇒ bloqué en silence ⇒ conversions à zéro sans explication.

## Téléversements

Taille → **octets magiques** (pas `File.type`, qui vient du client) → liste
blanche. Jamais dans le dossier public. **Nom regénéré** :
`../../etc/passwd` est un nom de fichier valide.

## Client HTTP du navigateur

Rafraîchissement sur 401 avec **verrou à un seul vol** (sinon dix 401
simultanés lancent dix rafraîchissements, neuf échouent, l'utilisateur est
déconnecté) · CSRF attaché automatiquement · **seuls `GET`/`HEAD` sont
rejoués** — rejouer un `POST` = commande ou retrait en double.

Codes d'erreur **stables** (`PIN_REQUIRED`) ; l'interface teste le code,
jamais le message.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…