Changelog

NeoFrag Reborn 1.1.0

Luandre 23 Aug 2026 10 min read 36
Table of contents
Table of contents

Security

  • Security review of the whole codebase, and fixes for the serious flaws it found:
    • Backups: backup archives (a copy of the database and of the config/ folder, which holds the passwords) can no longer be downloaded from a plain web address, under Apache or nginx; only the admin (Monitoring) hands them out. Their name now includes a random part that cannot be guessed. The log folder (logs/) is protected the same way.
    • Secret tokens: session IDs, form tokens and links sent by email (forgotten password, account validation) come from a secure random generator; they used to be predictable. These links expire after one hour, and a new request cancels the previous one.
    • Sign-in: two-factor authentication (2FA) and bans are checked whichever way you sign in — password, Discord, Google or GitHub account, "forgotten password" link — not just with the password.
    • Links in emails: the site address used in links sent by email, on return from a Discord, Google or GitHub sign-in and on return from a Stripe payment is the one saved at installation (config/url.php), no longer the one the request claims: an attacker can no longer get a link sent that leads to their own site.
    • Admin pages: a rigged attachment name (in a moderation report) or a fake IP address (X-Real-IP header, in the session history) could inject code into them; they are now checked and neutralized. A game server's welcome message, supplied by an outside service, is cleaned before display.
    • Admin actions: deleting, enabling or disabling, closing, approving, restoring, purging… now require a security token in the 23 modules that lacked one. They were plain links or token-less forms: a rigged link clicked by a logged-in administrator was enough to trigger the action.
    • Tools: scripts in the tools/ folder only run from the command line, never from a web address; on every change, continuous integration checks that no PHP dependency has a known flaw (composer audit).
    • Buttons silenced by the security policy (CSP): the site's strict CSP blocks actions written into the HTML (onclick="…"), so these buttons did nothing: cookie banner, number of rows in admin tables, trash and revision confirmations, attached file name in the messaging, forum mention bulk actions, click-to-select fields, the delete window's button. They are wired up differently and also work in content loaded without a page reload. The rows-per-page selector also still called jQuery, which had been removed.
  • Strict content security policy (CSP): served by the site with a token unique to each page, it refuses scripts written into the page without that token (unsafe-inline), code built on the fly (unsafe-eval) and embedded objects (object-src 'none'); scripts now only come from the site and a short list of addresses, as TinyMCE and CodeMirror are now hosted by the site.
  • Session renewed at sign-in: the session ID changes when you sign in; an ID planted before sign-in no longer gives access to the opened session.
  • Secrets encrypted in the database: the SMTP password and the two-factor authentication (2FA) key are encrypted (AES-256-GCM); a copy of the database no longer gives them away in plain text. An existing value is encrypted the next time it is saved.
  • Webhooks: a webhook can no longer target the server's internal network (private, local or reserved addresses refused, redirects not followed).

Added

  • CSS and JavaScript files always up to date: each file is requested with its modification date (?v=…), so the browser reloads it as soon as it changes — including a file overridden by a theme or uploaded by hand — without having to bump nf_version_css (still used when the file cannot be found).
  • Marketplace: the "Updates" window of the Themes & Addons page tells you when a new NeoFrag Reborn version is available; updating the core itself remains manual.
  • Addon updates: the same window compares installed addons with the marketplace catalog and installs new versions, along with their database migrations.
  • Installer: new look — NeoFrag Reborn logo, "Unofficial fork of NeoFrag" banner, credit to Michaël BILCOT and Jérémy VALENTIN (LGPLv3 license) in the footer, Inter and Space Grotesk fonts, teal colors.
  • Files: a file manager (folder tree, uploads, read permissions per file or per folder), ported from HiddenBlob's HiddenCMS (LGPLv3). Ships with the core.
  • Custom emojis (Emojis module, ships with the core): admins add named images, which :name: displays in forum posts and signatures, news, pages, events and recruitment, among others.
  • Newsletter: scheduled sending at the chosen date, in small batches handled by the site's scheduled task (cron) instead of all at once; open tracking (open rate per campaign, measured by an invisible image); reusable email templates; choice of recipients: all subscribers, members only, or a group.
  • Events: an event can repeat daily, weekly or monthly, for the chosen number of times — each date becomes an event in its own right. Participants, except those who declined, get an on-site reminder (notification bell) before the event, 24 hours before by default; reminders go through the site's scheduled task (cron).
  • Emoji reactions: six reactions to choose from (👍❤️😂😮😢😡) instead of a single heart, as on Discord or Facebook, each with its own count; existing "likes" become ❤️.
  • "Live status" widget (formerly the Twitch widget): follows several channels at once, on Twitch and YouTube (Twitch credentials and a YouTube API key required), with game, viewers, title, thumbnail and embedded player.
  • Composed pages: below its text, a page can show blocks from other modules (latest news, news from a category, latest articles, popular downloads), placed in the desired order and configured one by one when editing the page. The shortcode also accepts settings, for example [block:news.latest count=2].
  • Extend theme, by Chewbaka, ported to NeoFrag Reborn (Bootstrap 5, day and night modes), under the CC BY-NC-SA 4.0 license; available from the marketplace.
  • Instant search: the search widget suggests results from the second letter typed (news, forum, pages).
  • Sorting admin lists: ten lists (news, articles, classifieds, downloads, FAQ, guestbook, links, media, surveys, wiki) can be sorted by the chosen criterion.
  • Animated avatars: an animated GIF uploaded as an avatar stays animated — always if the server has Imagick, otherwise as long as it is no larger than 250 × 250 pixels.
  • Permissions: the permission grid opens in a window, without leaving the page.
  • Webmaster file manager (Monitoring, "Manage files" button): browse the site's files, edit them in an editor (CodeMirror), create, rename or delete them. The config/, logs/ and backups/ folders stay out of reach; every save keeps a .nfbak copy and goes into the audit log. Any write requires the webmaster password, separate from the account password and kept out of the database (set at installation or in Monitoring, "Webmaster security" card); once set, it is also required again to delete or purge backups and to change the scheduled-task key.
  • Release notes from a single source: tools/changelog-section.php extracts one version of this changelog (CHANGELOG.md), as Markdown or HTML; GitHub release notes are drawn from it, so their texts can no longer diverge.

Changed

  • "Everything included" installer: the wizard now has four steps (Requirements → Database → Administrator → Done). All shipped modules, widgets and themes are installed and enabled at the "Database" step, and the home page shows the news as soon as installation is over; the "Modules" step and its profiles are gone.
  • Bootstrap 4.6.2 → 5.3.8, and jQuery is no longer loaded: the site's JavaScript relies on a small in-house helper (window.NF). Nine jQuery or Bootstrap 4 plugins are replaced (notifications → Bootstrap 5 toasts, selectize → Tom Select, date picker → flatpickr, FullCalendar 3 → 6, color and icon pickers, tree view and gauges → in-house code, scrollbars → native scrolling), and jQuery UI by SortableJS. Four overlooked scripts still called jQuery: they are rewritten in 1.2.0.
  • Dark mode: tables, cards, drop-down menus and the text editor take on the theme's dark colors instead of staying white, in every theme.
  • Widget settings and page layouts: saved as JSON instead of PHP's serialization format, which closes a code-injection path; existing settings are still read.
  • Statistics charts: Chart.js (MIT license) replaces Highstock, a commercial library that prevented free redistribution of the CMS.

Fixed

  • MySQL 8: starting a topic or replying on the forum, splitting or merging topics, starting a conversation in the messaging, reordering Slider images… failed with a fatal error on MySQL 8, which rejected the way the site opened its transactions. They now go through the dedicated mysqli functions.
  • Emojis: an emoji — or any 4-byte character — in a text caused a database error. The connection and all tables switch to utf8mb4 (utf8mb4_unicode_ci collation, supported by MySQL 8 and MariaDB 10 alike; the MariaDB 11-only collations, which made installation fail elsewhere, are gone).
  • where('col', []) generated an empty condition (→ DELETE/UPDATE on the whole table): it now produces 1 = 0 (empty set).
  • Dates after 2038: a newsletter's scheduled sending, the scheduled publishing of a news item, article, gallery or page, and an event's dates could not go past January 19, 2038: beyond that, MariaDB refused to save them, without any message. These dates now go up to the year 9999; existing installations are updated by migration.
  • /user/login and /user/registration returned "page not found": the themes' "Login" and "Registration" buttons lead there when JavaScript is off or the link is opened in a new tab. These addresses now open the login or registration window.
  • Nebula: the "Registration" button stayed visible when registrations were closed, and led to a "page not found". It is now hidden in that case.
  • Discord widget: it gives the real cause of a failure (widget disabled on the server, unknown ID, network) instead of a generic message, shows the server's real logo (read from the public invite) and counts online members correctly — the list Discord provides stops at 100, which skewed the count for large servers.
  • TeamSpeak widget, tree view: it crashed under PHP 8 and fell back to the simple card. The tree of channels and clients is now drawn by the widget itself, with Font Awesome icons (no icon pack needed); a network error shows a generic message, without revealing the server's address or port.
  • Discord, Twitch and Game server widgets: they showed "unreachable" even when the service answered (the response was decoded twice). The site's requests also send a browser identifier (User-Agent): without it, services behind Cloudflare answered with a refusal (error 403).
  • Backups and Monitoring: creating a backup crashed on PHP-FPM servers, and failed under nginx or Plesk, which answered "page not found" to .json addresses; deleting or downloading a backup led to "page not found"; the Monitoring tree showed an error on first refresh. All fixed.
  • Marketplace unreachable: default URL switched to non-www (https://neofrag-reborn.xyz/marketplace).
  • Multiple file upload: the first file of a multiple upload made the upload fail ("page not found") — which is what blocked uploads in the Files module. For developers: uploaded_file() mistook index 0 for a missing index.
  • Webhooks: a member registering (user.registered), a new comment (comment.created) and a new forum topic (forum.topic) finally trigger their webhook; these events were offered but never sent.

Documentation

  • Documentation (wiki guides): for developers, forms (form() and form2()) and validating a widget's settings; for administrators, installation troubleshooting, an example of creating a role, and what to do when the marketplace is unreachable. A note explains how to configure nginx or Plesk, which answered "page not found" to .json addresses.

Read next

0
Comments

Manage my cookies

The site only places the cookies it needs to work: they do not require your consent. The other services belong to other companies; they only load if you accept them. Your choice is kept for six months, and you can change it at any time.

Needed by the site Always active

  • __Host-session Keeps you logged in and protects forms against fraudulent submissions. Until the browser is closed; one year with “Remember me”
  • nf_consent Keeps the choices you make in this window. 6 months
  • nf_fuseau Shows dates and times in your time zone. 1 year
  • Browser storage Keeps your choice between day and night mode, and the layout chosen for the list of articles. Until you clear it

Videos

Videos embedded in pages: the player comes from the platform, which receives your IP address and may place its cookies.

Music

Tracks and playlists embedded in pages: the player comes from the platform, which receives your IP address and may place its cookies.