En pruebas de caja negra contra localhost:3000, las respuestas no incluyen ninguna cabecera de seguridad y exponen la tecnología del servidor:
Faltan Content-Security-Policy, X-Frame-Options (o frame-ancestors), X-Content-Type-Options: nosniff, Referrer-Policy y Strict-Transport-Security.
Se envía X-Powered-By: Next.js, que revela el stack sin necesidad.
Lo que sí está bien (verificado en las mismas pruebas y vale la pena dejar registrado):
La API usa consultas parametrizadas de Prisma: los intentos de inyección SQL se guardaron como texto literal, no se ejecutaron.
No hay CORS abierto: un Origin arbitrario no recibe Access-Control-Allow-Origin.
El front no usa dangerouslySetInnerHTML, así que los valores con <script> que la API acepta sin sanear (por falta de validación, #21) se escapan al renderizar en React y no ejecutan. Queda como riesgo latente: si algún día se exporta a PDF, correo o HTML crudo, se vuelve XSS almacenado.
Qué estamos pagando hoy
Sin X-Frame-Options/CSP, el PDV se puede embeber en un iframe (clickjacking).
Sin nosniff y sin CSP, cualquier contenido reflejado o subido tiene menos barreras.
X-Powered-By facilita el fingerprinting del stack.
Arreglo propuesto
Agregar cabeceras de seguridad (helmet en Nest o headers() en next.config.ts): CSP, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy, y HSTS cuando haya HTTPS
Desactivar X-Powered-By (poweredByHeader: false en next.config.ts y app.disable('x-powered-by') en Express)
Revisar la CSP para que no rompa HeroUI ni los estilos inline
Techo de esta ronda
Solo cabeceras de respuesta. La autenticación va en #5, la validación de entrada en #4 y #21.
Superficie
API (apps/api)
Módulos
API / backend, Web / frontend, CI / infra
Esfuerzo
S — un PR chico
Riesgo de no tocarlo
Medio
### Qué es la deuda
En pruebas de caja negra contra `localhost:3000`, las respuestas no incluyen ninguna cabecera de seguridad y exponen la tecnología del servidor:
- Faltan `Content-Security-Policy`, `X-Frame-Options` (o `frame-ancestors`), `X-Content-Type-Options: nosniff`, `Referrer-Policy` y `Strict-Transport-Security`.
- Se envía `X-Powered-By: Next.js`, que revela el stack sin necesidad.
Lo que **sí está bien** (verificado en las mismas pruebas y vale la pena dejar registrado):
- La API usa consultas parametrizadas de Prisma: los intentos de inyección SQL se guardaron como texto literal, no se ejecutaron.
- No hay CORS abierto: un `Origin` arbitrario no recibe `Access-Control-Allow-Origin`.
- El front no usa `dangerouslySetInnerHTML`, así que los valores con `<script>` que la API acepta sin sanear (por falta de validación, #21) se escapan al renderizar en React y no ejecutan. Queda como riesgo latente: si algún día se exporta a PDF, correo o HTML crudo, se vuelve XSS almacenado.
### Qué estamos pagando hoy
- Sin `X-Frame-Options`/CSP, el PDV se puede embeber en un iframe (clickjacking).
- Sin `nosniff` y sin CSP, cualquier contenido reflejado o subido tiene menos barreras.
- `X-Powered-By` facilita el fingerprinting del stack.
### Arreglo propuesto
- [ ] Agregar cabeceras de seguridad (helmet en Nest o `headers()` en `next.config.ts`): CSP, `X-Frame-Options: DENY`, `X-Content-Type-Options: nosniff`, `Referrer-Policy`, y HSTS cuando haya HTTPS
- [ ] Desactivar `X-Powered-By` (`poweredByHeader: false` en `next.config.ts` y `app.disable('x-powered-by')` en Express)
- [ ] Revisar la CSP para que no rompa HeroUI ni los estilos inline
### Techo de esta ronda
Solo cabeceras de respuesta. La autenticación va en #5, la validación de entrada en #4 y #21.
### Superficie
API (apps/api)
### Módulos
API / backend, Web / frontend, CI / infra
### Esfuerzo
S — un PR chico
### Riesgo de no tocarlo
Medio
Emmanuel
was assigned by Carlos2026-10-02 20:02:32 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Qué es la deuda
En pruebas de caja negra contra
localhost:3000, las respuestas no incluyen ninguna cabecera de seguridad y exponen la tecnología del servidor:Content-Security-Policy,X-Frame-Options(oframe-ancestors),X-Content-Type-Options: nosniff,Referrer-PolicyyStrict-Transport-Security.X-Powered-By: Next.js, que revela el stack sin necesidad.Lo que sí está bien (verificado en las mismas pruebas y vale la pena dejar registrado):
Originarbitrario no recibeAccess-Control-Allow-Origin.dangerouslySetInnerHTML, así que los valores con<script>que la API acepta sin sanear (por falta de validación, #21) se escapan al renderizar en React y no ejecutan. Queda como riesgo latente: si algún día se exporta a PDF, correo o HTML crudo, se vuelve XSS almacenado.Qué estamos pagando hoy
X-Frame-Options/CSP, el PDV se puede embeber en un iframe (clickjacking).nosniffy sin CSP, cualquier contenido reflejado o subido tiene menos barreras.X-Powered-Byfacilita el fingerprinting del stack.Arreglo propuesto
headers()ennext.config.ts): CSP,X-Frame-Options: DENY,X-Content-Type-Options: nosniff,Referrer-Policy, y HSTS cuando haya HTTPSX-Powered-By(poweredByHeader: falseennext.config.tsyapp.disable('x-powered-by')en Express)Techo de esta ronda
Solo cabeceras de respuesta. La autenticación va en #5, la validación de entrada en #4 y #21.
Superficie
API (apps/api)
Módulos
API / backend, Web / frontend, CI / infra
Esfuerzo
S — un PR chico
Riesgo de no tocarlo
Medio