feat(submit): submit v3 con validación de integridad server-side [4G]
RPC transaccional SECURITY DEFINER (rpc_submit_response) como único camino de escritura. Dropea las policies WITH CHECK(true): cierra la falla donde anon podía insertar cualquier cosa. Validación server-side (7 checks) reusando el motor. Persistencia atómica con instance_id por instancia. Verificado contra Postgres real: instancias separadas, atomicidad, RLS. Riesgo residual de bypass por REST documentado (SEC-004). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
22
BACKLOG.md
22
BACKLOG.md
@@ -7,6 +7,28 @@
|
||||
|
||||
## Seguridad
|
||||
|
||||
### [SEC-004] RPC de submit es bypasseable vía REST directo (coherencia de flujo)
|
||||
- **Estado:** Riesgo residual documentado — no resuelto en Etapa 4G
|
||||
- **Contexto:** `rpc_submit_response` (migración `20260624000001_submit_rpc.sql`) es el único
|
||||
camino de escritura para `consent_records`/`responses`/`answers` (las policies `WITH CHECK(true)`
|
||||
que permitían INSERT directo a `anon` se eliminaron). La RPC valida lo ESTRUCTURAL en SQL
|
||||
(el `question_id` pertenece a la encuesta, la encuesta está viva, el consentimiento llegó).
|
||||
La validación de COHERENCIA DE FLUJO (visibilidad según `conditional_rules`, instancias
|
||||
legítimas de `4.1`) vive en TypeScript (`lib/submit-validation.ts`, reusa `lib/form-engine.ts`)
|
||||
porque reimplementarla en SQL violaría la regla de "no duplicar la lógica de flujo" (BRIEF 4G).
|
||||
- **Riesgo:** quien llame a `rpc_submit_response` directo por la REST API de Supabase (sin pasar
|
||||
por el Server Action de Next.js) puede mandar un payload con instancias/visibilidad incoherentes
|
||||
que igual pase las validaciones estructurales de la RPC.
|
||||
- **Por qué no es un incidente de privacidad:** el dato resultante sigue siendo anónimo
|
||||
(`respondent_id=NULL`), `is_sensitive` se sigue respetando, y queda sujeto al umbral k-anonimato
|
||||
en `agg_segment`/RPCs de dashboard igual que cualquier otra respuesta. Es un problema de calidad
|
||||
de datos de investigación (una respuesta lógicamente imposible podría colarse), no de exposición
|
||||
de datos.
|
||||
- **Cierre posible (no implementado):** firmar el payload en el Server Action (HMAC con un secreto
|
||||
server-only) y verificar la firma dentro de la RPC antes de insertar — así un caller directo sin
|
||||
el secreto no puede producir un payload válido. Evaluar costo/beneficio antes de priorizar.
|
||||
- **Dependencia:** no bloquea Sprint 4; evaluar junto con SEC-002 (sprint de compliance).
|
||||
|
||||
### [SEC-002] Sprint de compliance & seguridad
|
||||
- **Estado:** Diferido — pendiente de priorizar tras Sprint 4
|
||||
- **Contexto:** COMPLIANCE.md documenta el estado actual de seguridad (v2.1.0) y el roadmap
|
||||
|
||||
Reference in New Issue
Block a user