Licence EUPL-1.2 + hardening anti-abus
P1 — Licence : - Ajout du fichier LICENSE (EUPL-1.2 complet) - README mis à jour : section licence, table docs, vars d'environnement - En-têtes EUPL ajoutés dans les fichiers sources principaux (Flask, React) P2 — Hardening anti-abus : - Rate limiting Redis-ready (REDIS_URL) avec clé fingerprint + IP - Honeypot anti-bot : champ caché côté client + vérification serveur - Fingerprinting non-PII via FingerprintJS (hash SHA-256, colonne ideas.fingerprint_hash) - Cooldown session : cookie httpOnly signé HMAC-SHA256 (SECRET_KEY requis) - Détection de flood : alerte WARNING si > FLOOD_THRESHOLD soumissions / 5 min - hCaptcha stub : intégré, activable via HCAPTCHA_SECRET_KEY + VITE_HCAPTCHA_SITE_KEY - Nouvelles dépendances : redis (backend), @fingerprintjs/fingerprintjs + @hcaptcha/react-hcaptcha (frontend) - docs/SECURITE_ANTI_ABUS.md : documentation complète des seuils et de la configuration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
// Copyright (C) 2026 billisdead — Licence EUPL-1.2
|
||||
import React from "react";
|
||||
import { Switch, Route, Router as WouterRouter, Link } from "wouter";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { Toaster } from "@/components/ui/toaster";
|
||||
@@ -10,6 +12,8 @@ import Flyer from "@/pages/flyer";
|
||||
import Admin from "@/pages/admin";
|
||||
import { AccessibilityProvider } from "@/hooks/use-accessibility";
|
||||
import { AccessibilityPanel } from "@/components/accessibility-panel";
|
||||
import { setVisitorId } from "@workspace/api-client-react";
|
||||
import FingerprintJS from "@fingerprintjs/fingerprintjs";
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
@@ -77,6 +81,18 @@ function Router() {
|
||||
}
|
||||
|
||||
function App() {
|
||||
// Initialise FingerprintJS une seule fois au chargement
|
||||
// L'identifiant de visite est envoyé sur chaque appel API (header X-Visitor-Id)
|
||||
// Il est hashé côté serveur avant stockage — aucune donnée PII conservée
|
||||
React.useEffect(() => {
|
||||
FingerprintJS.load()
|
||||
.then((fp) => fp.get())
|
||||
.then((result) => setVisitorId(result.visitorId))
|
||||
.catch(() => {
|
||||
// Dégradation silencieuse si FingerprintJS indisponible
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<TooltipProvider>
|
||||
|
||||
Reference in New Issue
Block a user