Registro de cambios

NeoFrag Reborn 1.1.0

Luandre 23 ago 2026 11 min de lectura 36
Índice
Índice

Seguridad

  • Revisión de seguridad de todo el código, y corrección de los fallos graves que encontró:
    • Copias de seguridad: los archivos de copia de seguridad (una copia de la base de datos y de la carpeta config/, que contiene las contraseñas) ya no se pueden descargar desde una simple dirección web, ni con Apache ni con nginx; solo la administración (Monitorización) los entrega. Su nombre incluye ahora una parte aleatoria, imposible de adivinar. La carpeta de los registros (logs/) está protegida de la misma forma.
    • Tokens secretos: los identificadores de sesión, los tokens de los formularios y los enlaces enviados por correo (contraseña olvidada, validación de la cuenta) salen de un generador aleatorio seguro; eran predecibles. Estos enlaces caducan al cabo de una hora, y una nueva solicitud anula la anterior.
    • Inicio de sesión: la autenticación en dos pasos (2FA) y los baneos se comprueban sea cual sea la forma de iniciar sesión — contraseña, cuenta de Discord, Google o GitHub, enlace «contraseña olvidada» —, y ya no solo con la contraseña.
    • Enlaces en los correos: la dirección del sitio usada en los enlaces enviados por correo, al volver de un inicio de sesión con Discord, Google o GitHub y al volver de un pago con Stripe es la guardada en la instalación (config/url.php), y ya no la que anuncia la petición: un atacante ya no puede hacer enviar un enlace que lleve a su propio sitio.
    • Páginas de administración: un nombre de archivo adjunto trampeado (en una denuncia de moderación) o una dirección IP falsa (cabecera X-Real-IP, en el historial de sesiones) podían inyectar código en ellas; ahora se comprueban y se neutralizan. El mensaje de bienvenida de un servidor de juego, proporcionado por un servicio externo, se limpia antes de mostrarse.
    • Acciones de administración: eliminar, activar o desactivar, cerrar, aprobar, restaurar, purgar… exigen ahora un token de seguridad en los 23 módulos que no lo tenían. Eran simples enlaces o formularios sin token: un enlace trampeado, pulsado por un administrador con la sesión iniciada, bastaba para desencadenar la acción.
    • Herramientas: los scripts de la carpeta tools/ solo se ejecutan desde la línea de comandos, nunca desde una dirección web; en cada cambio, la integración continua comprueba que ninguna dependencia PHP tenga un fallo conocido (composer audit).
    • Botones silenciados por la política de seguridad (CSP): la CSP estricta del sitio bloquea las acciones escritas en el HTML (onclick="…"), así que estos botones no hacían nada: banner de cookies, número de filas de las tablas de administración, confirmaciones de la papelera y de las revisiones, nombre del archivo adjunto en la mensajería, acciones en lote de las menciones del foro, selección de un campo al hacer clic, botón de la ventana de eliminación. Se conectan de otra forma y funcionan también en el contenido cargado sin recargar la página. El selector del número de filas llamaba además a jQuery, que ya se había retirado.
  • Política de seguridad del contenido (CSP) estricta: servida por el sitio con un token propio de cada página, rechaza los scripts escritos en la página sin ese token (unsafe-inline), el código construido sobre la marcha (unsafe-eval) y los objetos incrustados (object-src 'none'); los scripts solo vienen ya del sitio y de una breve lista de direcciones, ya que TinyMCE y CodeMirror pasan a estar alojados en el propio sitio.
  • Sesión renovada al iniciar sesión: el identificador de sesión cambia al iniciar sesión; un identificador impuesto antes del inicio de sesión ya no da acceso a la sesión abierta.
  • Secretos cifrados en la base de datos: la contraseña SMTP y la clave de la autenticación en dos pasos (2FA) están cifradas (AES-256-GCM); una copia de la base de datos ya no las entrega en claro. Un valor existente se cifra la próxima vez que se guarda.
  • Webhooks: un webhook ya no puede apuntar a la red interna del servidor (direcciones privadas, locales o reservadas rechazadas, redirecciones no seguidas).

Añadido

  • Archivos CSS y JavaScript siempre al día: cada archivo se pide con su fecha de modificación (?v=…), de modo que el navegador lo recarga en cuanto cambia — incluido un archivo sustituido por un tema o subido a mano —, sin tener que aumentar nf_version_css (que se sigue usando cuando no se encuentra el archivo).
  • Marketplace: la ventana «Actualizaciones» de la página Temas & Addons avisa de que hay una nueva versión de NeoFrag Reborn disponible; la actualización del núcleo en sí sigue siendo manual.
  • Actualizaciones de los addons: la misma ventana compara los addons instalados con el catálogo del marketplace e instala las nuevas versiones, con sus migraciones de base de datos.
  • Instalador: nueva presentación — logotipo de NeoFrag Reborn, banner «Fork no oficial de NeoFrag», crédito a Michaël BILCOT y Jérémy VALENTIN (licencia LGPLv3) en el pie de página, tipografías Inter y Space Grotesk, colores turquesa.
  • Archivos: un gestor de archivos (árbol de carpetas, subida, permisos de lectura por archivo o por carpeta), portado de HiddenCMS, de HiddenBlob (LGPLv3). Incluido con el núcleo.
  • Emojis personalizados (módulo Emojis, incluido con el núcleo): la administración añade imágenes con nombre, que :nombre: muestra en los mensajes y firmas del foro, las noticias, las páginas, los eventos y el reclutamiento, entre otros.
  • Newsletter: envío programado en la fecha elegida, en pequeños lotes tratados por la tarea programada del sitio (cron) en lugar de enviarlo todo de golpe; seguimiento de aperturas (tasa de apertura por campaña, medida mediante una imagen invisible); plantillas de correo reutilizables; elección de destinatarios: todos los suscriptores, solo los miembros o un grupo.
  • Eventos: un evento puede repetirse cada día, cada semana o cada mes, el número de veces elegido — cada fecha se convierte en un evento por derecho propio. Los participantes, salvo los que han declinado, reciben un recordatorio en el sitio (campana de notificaciones) antes del evento, 24 horas antes por defecto; los recordatorios pasan por la tarea programada del sitio (cron).
  • Reacciones con emoji: seis reacciones a elegir (👍❤️😂😮😢😡) en lugar de un solo corazón, como en Discord o Facebook, cada una con su recuento; los antiguos «me gusta» se convierten en ❤️.
  • Widget «Estado en directo» (el antiguo widget de Twitch): sigue varios canales a la vez, en Twitch y en YouTube (credenciales de Twitch y clave de API de YouTube necesarias), con juego, espectadores, título, miniatura y reproductor integrado.
  • Páginas compuestas: bajo su texto, una página puede mostrar bloques de otros módulos (últimas noticias, noticias de una categoría, últimos artículos, descargas populares), colocados en el orden deseado y configurados uno a uno al editar la página. El código corto acepta también ajustes, por ejemplo [block:news.latest count=2].
  • Tema Extend, de Chewbaka, portado a NeoFrag Reborn (Bootstrap 5, modos día y noche), con licencia CC BY-NC-SA 4.0; disponible en el marketplace.
  • Búsqueda instantánea: el widget de búsqueda propone resultados desde la segunda letra escrita (noticias, foro, páginas).
  • Ordenación de las listas de administración: diez listas (noticias, artículos, anuncios clasificados, descargas, FAQ, libro de visitas, enlaces, medios, encuestas, wiki) se ordenan según el criterio elegido.
  • Avatares animados: un GIF animado subido como avatar sigue animado — siempre si el servidor dispone de Imagick, y si no, mientras no supere los 250 × 250 píxeles.
  • Permisos: la cuadrícula de permisos se abre en una ventana, sin salir de la página.
  • Gestor de archivos del webmaster (Monitorización, botón «Gestionar archivos»): recorrer los archivos del sitio, editarlos en un editor (CodeMirror), crearlos, renombrarlos o eliminarlos. Las carpetas config/, logs/ y backups/ quedan fuera de alcance; cada guardado conserva una copia .nfbak y entra en el registro de auditoría. Toda escritura exige la contraseña de webmaster, distinta de la de la cuenta y guardada fuera de la base de datos (definida en la instalación o en Monitorización, tarjeta «Seguridad webmaster»); una vez definida, se vuelve a pedir también para eliminar o purgar copias de seguridad y para cambiar la clave de la tarea programada.
  • Notas de versión de una sola fuente: tools/changelog-section.php extrae una versión de este registro de cambios (CHANGELOG.md), en Markdown o en HTML; las notas de las releases de GitHub salen de ahí, y sus textos ya no pueden divergir.

Cambiado

  • Instalador «todo incluido»: el asistente pasa a cuatro pasos (Requisitos → Base de datos → Administrador → Terminado). Todos los módulos, widgets y temas incluidos se instalan y activan en el paso «Base de datos», y la página de inicio muestra las noticias en cuanto termina la instalación; el paso «Módulos» y sus perfiles desaparecen.
  • Bootstrap 4.6.2 → 5.3.8, y jQuery ya no se carga: el JavaScript del sitio se apoya en una pequeña herramienta propia (window.NF). Nueve extensiones de jQuery o de Bootstrap 4 se sustituyen (notificaciones → toasts de Bootstrap 5, selectize → Tom Select, selector de fecha → flatpickr, FullCalendar 3 → 6, selectores de color y de icono, árbol y medidores → código propio, barras de desplazamiento → desplazamiento nativo), y jQuery UI por SortableJS. Cuatro scripts olvidados seguían llamando a jQuery: se reescriben en la 1.2.0.
  • Modo oscuro: las tablas, tarjetas, menús desplegables y el editor de texto toman los colores oscuros del tema en lugar de quedarse blancos, en todos los temas.
  • Ajustes de los widgets y disposición de las páginas: guardados en JSON en lugar del formato de serialización de PHP, lo que cierra una vía de inyección de código; los ajustes antiguos se siguen leyendo.
  • Gráficos de las estadísticas: Chart.js (licencia MIT) sustituye a Highstock, una biblioteca comercial que impedía redistribuir libremente el CMS.

Corregido

  • MySQL 8: abrir un tema o responder en el foro, dividir o fusionar temas, crear una conversación en la mensajería, reordenar las imágenes del Slider… fallaban con un error fatal en MySQL 8, que rechazaba la forma en que el sitio abría sus transacciones. Ahora pasan por las funciones previstas de mysqli.
  • Emojis: un emoji — o cualquier carácter de 4 bytes — en un texto provocaba un error de base de datos. La conexión y todas las tablas pasan a utf8mb4 (intercalación utf8mb4_unicode_ci, reconocida tanto por MySQL 8 como por MariaDB 10; las intercalaciones propias de MariaDB 11, que hacían fallar la instalación en otros servidores, desaparecen).
  • where('col', []) generaba una condición vacía (→ DELETE/UPDATE sobre toda la tabla): ahora produce 1 = 0 (conjunto vacío).
  • Fechas posteriores a 2038: el envío programado de una newsletter, la publicación programada de una noticia, un artículo, una galería o una página, y las fechas de un evento no podían pasar del 19 de enero de 2038: más allá, MariaDB rechazaba guardarlas, sin ningún mensaje. Estas fechas llegan ahora hasta el año 9999; las instalaciones existentes se actualizan mediante una migración.
  • /user/login y /user/registration respondían «página no encontrada»: los botones «Iniciar sesión» y «Registro» de los temas llevan allí cuando JavaScript está desactivado o el enlace se abre en una nueva pestaña. Estas direcciones abren ahora la ventana de inicio de sesión o de registro.
  • Nebula: el botón «Registro» seguía visible cuando los registros estaban cerrados, y llevaba a una página no encontrada. Ahora se oculta en ese caso.
  • Widget de Discord: da la verdadera causa de un fallo (widget desactivado en el servidor, identificador desconocido, red) en lugar de un mensaje genérico, muestra el verdadero logotipo del servidor (leído en la invitación pública) y cuenta bien los miembros en línea — la lista que proporciona Discord se detiene en 100, lo que falseaba el recuento de los servidores grandes.
  • Widget de TeamSpeak, vista en árbol: fallaba con PHP 8 y volvía a la tarjeta simple. El árbol de canales y clientes lo dibuja ahora el propio widget, con iconos de Font Awesome (ya no hace falta un paquete de iconos); un error de red muestra un mensaje genérico, sin revelar la dirección ni el puerto del servidor.
  • Widgets de Discord, Twitch y Servidor de juego: mostraban «inaccesible» incluso cuando el servicio respondía (la respuesta se decodificaba dos veces). Las peticiones del sitio envían además un identificador de navegador (User-Agent): sin él, los servicios protegidos por Cloudflare respondían con un rechazo (error 403).
  • Copias de seguridad y Monitorización: crear una copia de seguridad fallaba en los servidores con PHP-FPM, y fallaba con nginx o Plesk, que respondían «página no encontrada» a las direcciones en .json; eliminar o descargar una copia de seguridad llevaba a una página no encontrada; el árbol de la Monitorización mostraba un error en la primera actualización. Todo corregido.
  • Marketplace inaccesible: URL por defecto cambiada a sin www (https://neofrag-reborn.xyz/marketplace).
  • Subida de varios archivos: el primer archivo de una subida múltiple hacía fallar la subida («página no encontrada») — era lo que bloqueaba la subida en el módulo Archivos. Para los desarrolladores: uploaded_file() tomaba el índice 0 por la ausencia de índice.
  • Webhooks: el registro de un miembro (user.registered), un nuevo comentario (comment.created) y un nuevo tema del foro (forum.topic) disparan por fin su webhook; estos eventos se ofrecían pero nunca se emitían.

Documentación

  • Documentación (guías de la wiki): para los desarrolladores, los formularios (form() y form2()) y la validación de los ajustes de un widget; para los administradores, la solución de problemas de la instalación, un ejemplo de creación de un rol y qué hacer cuando el marketplace es inaccesible. Una nota explica cómo configurar nginx o Plesk, que respondían «página no encontrada» a las direcciones en .json.

Lee también

0
Comentarios

Gestionar mis cookies

El sitio solo instala las cookies necesarias para su funcionamiento: no requieren su consentimiento. Los demás servicios pertenecen a otras empresas; solo se cargan si los acepta. Su elección se guarda seis meses, y puede cambiarla en cualquier momento.

Necesarias para el sitio Siempre activas

  • __Host-session Mantiene su sesión iniciada y protege los formularios contra envíos fraudulentos. Hasta que se cierra el navegador; un año con «Recordarme»
  • nf_consent Guarda las elecciones que hace en esta ventana. 6 meses
  • nf_fuseau Muestra las fechas y las horas en su zona horaria. 1 año
  • Almacenamiento del navegador Guarda su elección entre el modo día y el modo noche, y la presentación elegida para la lista de artículos. Hasta que lo vacíe

Vídeos

Los vídeos integrados en las páginas: el reproductor viene de la plataforma, que recibe su dirección IP y puede instalar sus cookies.

Música

Las canciones y listas de reproducción integradas en las páginas: el reproductor viene de la plataforma, que recibe su dirección IP y puede instalar sus cookies.