Foro: correcciones de la revisión de seguridad y correctitud

- CSRF real en las vistas mutadoras con @csrf_protect (el middleware global no
  estaba activo; verificado: POST sin token -> 403). Se documenta el hueco global.
- bloquea acceso a temas de foros ocultos/borrados por URL directa (view_topic y reply)
- conteo de posts respeta borrados para moderadores (paginación correcta)
- tema bloqueado impide editar/borrar posts a no-moderadores (_topic_locked_for)
- moderador ve el formulario de respuesta en temas bloqueados (can_reply)
- filtro forum_safe: sanea el HTML también al renderizar (defensa en profundidad)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 17:34:03 +00:00
parent 071ba031a1
commit 89ea16ba4d
6 changed files with 81 additions and 14 deletions
+14 -2
View File
@@ -51,8 +51,20 @@ en `forum/permissions.py`:
guardar — `forum/sanitize.py` — evitando el XSS que tenía el original (que
renderizaba HTML del editor sin filtrar). Se renderiza con `|safe` ya saneado.
- **Todas** las acciones que modifican datos (publicar, responder, editar, mover,
bloquear/desbloquear, fijar, borrar/restaurar temas y posts) van por **POST con
CSRF**. Las vistas de moderación rechazan GET.
bloquear/desbloquear, fijar, borrar/restaurar temas y posts) van por **POST**, y
las vistas mutadoras llevan **`@csrf_protect`** (fuerza la validación CSRF por
vista aunque el middleware global no esté activo).
- El HTML de los posts también se **sanea al renderizar** con el filtro
`forum_safe` (defensa en profundidad frente a datos heredados sin sanear).
- Acceso a temas de foros ocultos/borrados bloqueado también por URL directa
(no solo en los listados).
> ⚠️ **Recomendación para todo el sitio** (fuera del foro): `novawow/settings.py`
> no incluye `django.middleware.csrf.CsrfViewMiddleware`, por lo que el resto de
> formularios POST del portal (app `home`) **no** validan CSRF. El foro está
> protegido con `@csrf_protect`, pero conviene activar el middleware global y
> revisar que las vistas POST de `home` lleven `{% csrf_token %}` (algunas ya lo
> llevan; las AJAX usan `@csrf_exempt`).
## Editor