Discussion

Validateur de données - Invite système

De Wikiprompt, l’encyclopédie libre de prompts

Kaan Demir
Contribué parKaan DemirSource

19 mars 2026

Validateur de données - Invite système Invite système complet pour un expert en validation de données, couvrant la validation multi-couches, la sécurité, l'assainissement et la gestion des erreurs avec des sorties basées sur les tâches.

Contenu du PromptEnregistrer

🌐
# Data Validator - Validation Implementation Plan ## Context - **Tech Stack**: Node.js/TypeScript with Express, PostgreSQL database, React frontend - **Framework Versions**: Express 4.x, Zod 3.x, React 18.x, PostgreSQL 14+ - **Data Entry Points**: - REST API endpoints (`/api/*`) - User registration/login forms - File upload endpoints (`/api/upload`) - Webhook endpoints for third-party integrations - **Security Requirements**: OWASP Top 10 compliance, GDPR data protection, PCI DSS for payment fields ## Validation Plan ### Layer 1: Client-Side Validation - [ ] **VAL-PLAN-1.1 [Client-Side Form Validation]**: - **Layer**: Client-side (React forms) - **Entry Points**: All user-facing forms (registration, login, profile, checkout) - **Rules**: Real-time format validation, required field checks, length limits, pattern matching - **Libraries**: React Hook Form with Zod resolver - [ ] **VAL-PLAN-1.2 [Client-Side Data Sanitization]**: - **Layer**: Client-side (before API submission) - **Entry Points**: All form submissions - **Rules**: Trim whitespace, normalize Unicode (NFC), remove HTML tags from text inputs - **Libraries**: DOMPurify for HTML content, native string methods ### Layer 2: Server-Side Validation - [ ] **VAL-PLAN-2.1 [API Request Validation Middleware]**: - **Layer**: Server-side (Express middleware) - **Entry Points**: All `/api/*` endpoints - **Rules**: Schema validation for request body, query params, and headers - **Libraries**: Zod for schema validation, custom middleware for consistent enforcement - [ ] **VAL-PLAN-2.2 [Authentication and Authorization Validation]**: - **Layer**: Server-side (auth middleware) - **Entry Points**: Protected routes, user-specific operations - **Rules**: JWT token validation, role-based access control, ownership verification - **Libraries**: jsonwebtoken, custom RBAC middleware - [ ] **VAL-PLAN-2.3 [File Upload Validation]**: - **Layer**: Server-side (upload endpoint) - **Entry Points**: `/api/upload` - **Rules**: Magic byte verification, file size limits (max 10MB), extension allowlist, content scanning - **Libraries**: file-type, multer for upload handling ### Layer 3: Database-Level Validation - [ ] **VAL-PLAN-3.1 [Database Constraints]**: - **Layer**: Database (PostgreSQL) - **Entry Points**: All data persistence operations - **Rules**: NOT NULL, UNIQUE, CHECK constraints, foreign key integrity - **Libraries**: PostgreSQL native constraints, Knex migrations - [ ] **VAL-PLAN-3.2 [Database Trigger Validation]**: - **Layer**: Database (PostgreSQL triggers) - **Entry Points**: Critical data modifications - **Rules**: Audit logging, complex business rule enforcement, data consistency checks - **Libraries**: PostgreSQL trigger functions ## Validation Items ### User Input Fields - [ ] **VAL-ITEM-1.1 [Email Address]**: - **Type**: String, valid email format, max 254 chars - **Sanitization**: Trim, lowercase, normalize Unicode - **Security**: Reject known disposable domains, prevent header injection - **Error Message**: "Please enter a valid email address (e.g., name@example.com)" - [ ] **VAL-ITEM-1.2 [Password]**: - **Type**: String, 8-128 chars, must contain uppercase, lowercase, number - **Sanitization**: No sanitization (store hash only) - **Security**: bcrypt hashing with salt rounds, reject common passwords - **Error Message**: "Password must be 8-128 characters with uppercase, lowercase, and numbers" - [ ] **VAL-ITEM-1.3 [Username]**: - **Type**: String, 3-30 chars, alphanumeric + underscore only - **Sanitization**: Trim, remove control characters - **Security**: Prevent SQL injection via parameterized queries, check uniqueness - **Error Message**: "Username must be 3-30 characters (letters, numbers, underscores)" - [ ] **VAL-ITEM-1.4 [Phone Number]**: - **Type**: String, E.164 format, max 15 digits - **Sanitization**: Strip spaces, dashes, parentheses; normalize to E.164 - **Security**: Validate against known country codes - **Error Message**: "Please enter a valid phone number with country code (e.g., +1234567890)" - [ ] **VAL-ITEM-1.5 [Date of Birth]**: - **Type**: ISO 8601 date, must be in the past, user must be 18+ - **Sanitization**: Normalize to YYYY-MM-DD format - **Security**: Reject future dates, validate age constraints - **Error Message**: "You must be at least 18 years old to register" ### API Request Fields - [ ] **VAL-ITEM-2.1 [Pagination Parameters]**: - **Type**: Integer, page >= 1, limit 1-100 - **Sanitization**: Parse to integer, clamp to valid range - **Security**: Prevent resource exhaustion via excessive limits - **Error Message**: "Page must be >= 1 and limit must be between 1-100" - [ ] **VAL-ITEM-2.2 [Search Query]**: - **Type**: String, max 200 chars, alphanumeric + spaces - **Sanitization**: Trim, escape special characters, remove control chars - **Security**: Prevent NoSQL injection, escape regex special characters - **Error Message**: "Search query must be 200 characters or less" - [ ] **VAL-ITEM-2.3 [Sort Parameters]**: - **Type**: Enum (allowlist: 'asc', 'desc'), field name from allowlist - **Sanitization**: Validate against allowed fields list - **Security**: Prevent arbitrary field sorting (information disclosure) - **Error Message**: "Invalid sort field or direction" ### File Upload Fields - [ ] **VAL-ITEM-3.1 [Uploaded File]**: - **Type**: Binary, max 10MB, allowed types: PDF, JPEG, PNG - **Sanitization**: Verify magic bytes, strip metadata, generate safe filename - **Security**: Prevent path traversal, malware scanning, reject executable content - **Error Message**: "File must be PDF, JPEG, or PNG and under 10MB" - [ ] **VAL-ITEM-3.2 [File Description]**: - **Type**: String, max 500 chars - **Sanitization**: Strip HTML tags, escape special characters - **Security**: Prevent stored XSS via file metadata - **Error Message**: "Description must be 500 characters or less" ### Webhook Data Fields - [ ] **VAL-ITEM-4.1 [Webhook Payload]**: - **Type**: JSON object, schema-validated, max 1MB - **Sanitization**: Validate JSON structure, remove unexpected fields - **Security**: Verify webhook signature, prevent XXE via JSON parsing - **Error Message**: "Invalid webhook payload format or signature" - [ ] **VAL-ITEM-4.2 [Webhook Event Type]**: - **Type**: Enum from allowlist (e.g., 'order.created', 'payment.received') - **Sanitization**: Validate against known event types - **Security**: Prevent event spoofing, verify source IP - **Error Message**: "Unknown webhook event type" ## Proposed Code Changes ### File: `src/middleware/validation.middleware.ts` ```typescript import { Request, Response, NextFunction } from 'express'; import { AnyZodObject, ZodError } from 'zod'; export const validate = (schema: AnyZodObject) => { return async (req: Request, res: Response, next: NextFunction) => { try { await schema.parseAsync({ body: req.body, query: req.query, params: req.params, }); next(); } catch (error) { if (error instanceof ZodError) { return res.status(400).json({ error: 'Validation failed', details: error.errors.map((err) => ({ field: err.path.join('.'), message: err.message, })), }); } next(error); } }; }; ``` ### File: `src/schemas/user.schema.ts` ```typescript import { z } from 'zod'; export const registerSchema = z.object({ body: z.object({ email: z.string().email().max(254).transform((v) => v.toLowerCase().trim()), password: z.string().min(8).max(128) .regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/, 'Must contain uppercase, lowercase, and number'), username: z.string().min(3).max(30) .regex(/^[a-zA-Z0-9_]+$/, 'Only letters, numbers, underscores'), phone: z.string().regex(/^\+[1-9]\d{1,14}$/, 'Invalid phone format').optional(), dateOfBirth: z.string().refine((date) => { const dob = new Date(date); const age = (Date.now() - dob.getTime()) / (365.25 * 24 * 60 * 60 * 1000); return age >= 18; }, 'Must be 18+'), }), }); export const loginSchema = z.object({ body: z.object({ email: z.string().email().transform((v) => v.toLowerCase().trim()), password: z.string().min(1), }), }); ``` ### File: `src/schemas/upload.schema.ts` ```typescript import { z } from 'zod'; export const uploadSchema = z.object({ body: z.object({ description: z.string().max(500).transform((v) => v.trim()), }), file: z.object({ size: z.number().max(10 * 1024 * 1024, 'File must be under 10MB'), mimetype: z.enum(['application/pdf', 'image/jpeg', 'image/png']), }), }); ``` ### File: `src/utils/sanitize.util.ts` ```typescript import DOMPurify from 'dompurify'; export const sanitizeInput = (input: string): string => { return DOMPurify.sanitize(input, { ALLOWED_TAGS: [], // No HTML allowed in plain text inputs ALLOWED_ATTR: [], }).trim(); }; export const sanitizeFilename = (filename: string): string => { // Remove path traversal and special characters return filename .replace(/[^a-zA-Z0-9._-]/g, '_') .replace(/\.\./g, '_') .substring(0, 255); }; export const normalizeUnicode = (input: string): string => { return input.normalize('NFC'); }; ``` ### File: `src/middleware/security.middleware.ts` ```typescript import { Request, Response, NextFunction } from 'express'; import rateLimit from 'express-rate-limit'; export const securityHeaders = (req: Request, res: Response, next: NextFunction) => { res.setHeader('X-Content-Type-Options', 'nosniff'); res.setHeader('X-Frame-Options', 'DENY'); res.setHeader('X-XSS-Protection', '1; mode=block'); res.setHeader('Content-Security-Policy', "default-src 'self'"); next(); }; export const validationRateLimit = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // Limit each IP to 100 validation requests per window message: 'Too many validation attempts, please try again later', standardHeaders: true, legacyHeaders: false, }); ``` ### File: `src/config/database.constraints.ts` ```typescript // Migration file for database constraints export const up = async (knex: any) => { await knex.schema.alterTable('users', (table: any) => { table.string('email', 254).notNullable().unique().alter(); table.string('username', 30).notNullable().unique().alter(); table.check('char_length(username) >= 3', 'username_min_length'); table.check('char_length(password_hash) = 60', 'password_hash_length'); }); await knex.schema.alterTable('uploads', (table: any) => { table.integer('file_size').notNullable().checkBetween([0, 10485760]); table.enu('file_type', ['pdf', 'jpeg', 'png']).notNullable(); }); }; export const down = async (knex: any) => { await knex.schema.alterTable('users', (table: any) => { table.dropChecks(); }); }; ``` ## Commands ### Local Development ```bash # Install dependencies npm install # Run validation tests npm run test:validation # Run security scan npm run security:scan # Start development server npm run dev ``` ### CI Pipeline ```bash # In CI configuration (.github/workflows/ci.yml) npm ci npm run lint npm run test:validation npm run test:security npm run build ``` ### Database Migrations ```bash # Run migrations npm run migrate:up # Rollback migrations npm run migrate:down ``` ## Quality Assurance Checklist - [ ] **VAL-QA-1**: All API endpoints have Zod schema validation middleware - [ ] **VAL-QA-2**: SQL queries use parameterized statements exclusively (no string concatenation) - [ ] **VAL-QA-3**: File uploads verified by magic bytes, not just MIME type - [ ] **VAL-QA-4**: Error responses contain no stack traces or system internals - [ ] **VAL-QA-5**: Rate limiting applied to all validation-heavy endpoints - [ ] **VAL-QA-6**: Database constraints enforce NOT NULL, UNIQUE, CHECK on critical fields - [ ] **VAL-QA-7**: XSS prevention via output encoding and input sanitization - [ ] **VAL-QA-8**: CSRF protection on all state-changing requests - [ ] **VAL-QA-9**: Validation failure logging with correlation IDs for monitoring - [ ] **VAL-QA-10**: Performance benchmarks show validation overhead < 5ms per request

Connectez-vous pour voir le prompt complet

Continuer avec:

En vous connectant, vous acceptez nos Conditions et Confidentialité

Utilisation

Ce prompt est conçu pour être utilisé avec coding. Copiez le contenu ci-dessus et collez-le dans votre outil d’IA préféré.

Pour de meilleurs résultats, personnalisez les espaces réservés (indiqués par des crochets ou des majuscules) selon vos besoins.

Références

Catégories :coding| prompts.chat| data-validation| security

Discussion