HTML TemplatesFlash TemplatesWordPress ThemesDrupal Themese107 ThemesFree Joomla TemplatesXOOPS ThemesphpBB StylesFree SMF ThemesMagento ThemesOpenCart ThemesosCommerce TemplatesPrestaShop TemplatesVirtueMart TemplatesZen Cart TemplatesTumblr Themes
Website Templates | Coupons | Blog | News | Reviews | Tutorials | Login

News

2024 Update - Site Sunset

I will soon lock down the b2evolution.net site. It will become read only and neither you nor me will be able to post new content to it.

  • I will keep the read-only site up for reference for as long as practical. I might convert it to all static pages at some point (and still retain the content).
  • I will post future updates on stateoftheevolution.com.
  • You may continue to discuss issues on GitHub.

Original post blogged on b2evolution.

Read more...

Posted July 10, 2024 | 2:51 pm

View all b2evolution News...

Drupal 11.4.0 is now available

The fourth feature release of Drupal 11 is another performance breakthrough. Using only a third of the database and cache lookups compared to Drupal 11.0 and 10.6 for the same requests. It also comes with 15-25% better compression of JS and CSS, much faster translation file handling, a new native command line interface, improved password hashing and a lot more.

Drupal 11.4.0 is now available

New in Drupal 11.4

Biggest performance improvement of the decade (again!)

With Drupal 11.3, we announced that it was the biggest performance improvement of the decade. Drupal 11.4 is arguably the biggest performance improvement of the decade again!

Drupal 11.4 reduces database queries by half compared to 11.3 across a wide range of requests due to optimizations in how entity fields are loaded.

Now, on a completely cold cache, Drupal 11.4 will execute just over 1/3rd of the database and cache lookups compared to Drupal 11.0 or 10.6, representing hundreds of milliseconds saved.

As well as entity loading, entity listing queries have also been significantly improved via reducing the number of table joins, leading to fewer slow queries. This should particularly benefit sites using JSON:API.

To reduce the cost of rendering menus and improve render cache hit rates, menu blocks now have a configuration option to not generate CSS classes for ancestor menu links.

Applying recipes, such as setting up Drupal CMS is twice as fast

We have made recipe-based site installation twice as fast. This significantly improves the UX of installing Drupal CMS and other site recipes. Installing individual recipes is also markedly faster.

Translation file handling: dramatically faster with a modern API

Importing translations during the installer or during site operation is now much faster. On a test site with 66 projects and 38 languages, checking for translation updates was 87% faster on Drupal 11.4 compared to 11.3.

The APIs handling translation files and import have undergone an extensive modernization effort. All .inc files and several important APIs in locale.module have been deprecated and updated to OOP with special attention paid to performance and organization.

15-25% better compression of JS and CSS

Drupal now supports Brotli compression for aggregated CSS and JavaScript files in addition to the existing gzip compression. Brotli typically provides 15-25% better compression ratios than gzip, resulting in faster page loads for browsers that support it. The feature relies on the PHP Brotli extension: ext-brotli.

Immediate security updates of key dependencies allowed in core-recommended

The drupal/core-recommended package no longer pins minor versions for dependencies like Guzzle, Twig, and Symfony Polyfills. In the past, stricter version rules and Composer 2.9's blocking behaviour forced sites to wait for a new Drupal release to get important security fixes. Now, you can install these security fixes immediately. Since the updated dependencies at that time may not have been tested with Drupal core yet, site owners should ensure adequate quality assurance occurs before deploying to production.

New experimental extensible native command line interface

A new extensible ./vendor/bin/dr command line interface was added. While Drupal already includes a CLI script with hardcoded commands, it is not extensible. This new interface was built by a team which included the maintainers of the Drush utility. Drush has been a mainstay for people using Drupal with the command line. Now a transitional period starts as Drush is gradually replaced with the core dr CLI over time. Learn how to make your existing Drush commands compatible.

Simplified and updated default experience

The default installation, the Standard profile, is now leaner. It no longer includes the Article and Page content types, and commenting is disabled by default. Further core startup simplifications are planned for upcoming releases.
The Navigation module is now enabled in the standard administrative interface. The legacy Toolbar module remains available but is scheduled for removal in Drupal 12.

Better entity display management for display builders such as Drupal Canvas

A new overview page has been added under the "Manage display" tab for content entity bundles. Previously, this tab led to the form editing the default view mode. Now, it lists all display modes for the bundle with their label and description and allows one to toggle the enabled/disabled status. The listing makes it easier to integrate tools such as Drupal Canvas.

Distraction-free editing available with CKEditor

Text formats using CKEditor can now be configured to include the FullScreen plugin. This plugin lets users expand the editor to the whole browser viewport, giving more space to comfortably edit content in a distraction-free environment.

Improved password hashing available

The password hashing algorithm is now configurable. The new argon2id option provides much stronger hashing compared to the old bcrypt method. Drupal 12 will default to argon2id, but your site can already start to adopt it. If you update the setting, users' passwords will be rehashed on their next login.

Do more with PHP attributes

You can now use attributes on your controllers to specify the routes the controller is used for. Any class in a module's Controller namespace (for example, Drupal\example\Controller) that have the Symfony\Component\Routing\Attribute\Route attribute will be picked up as route definitions. Even multiple routes can be defined on one class. This supplements the existing .routing.yml based declarations.

It is now possible to use the Drupal\Core\Entity\Attribute\Bundle attribute to define bundle classes, when in need of specific logic for an entity subtype. This previously required an entity_type_info or entity_type_info_alter implementation.

No more .theme files, only a few .module files left

All .theme and .theme-settings.php files in core have moved to PHP classes. Support for .theme files is still planned to be retained in Drupal 12 to ease the transition, but will be removed in Drupal 13.

Most .module files have been converted too: 32 modules are fully converted to PHP classes, with 11 modules remaining (4 of which are deprecated for removal in Drupal 12).

A team of 26 key contributors worked on 57 issues since January 2026 to get here, making Drupal's code more consistent. Also thanks to the dozens of users that worked on the many decades old issues that this initiative built upon.

Front controllers now utilize symfony/runtime

Drupal now integrates the Symfony Runtime component to separate bootstrapping logic from request handling. This provides a clear separation of concerns between preparing the environment (runtime) and handling a request, which will also later enable better integration with FrankenPHP.

Write faster tests with new helper method

A new trait for kernel tests, HttpKernelUiHelperTrait, allows kernel tests to make HTTP requests to the test site and make assertions against the returned content. This has the potential for many browser tests to be converted to kernel tests, which are much faster to run because unlike browser tests, they don't fully set up a test site by running the Drupal installer.

New experimental administrative theme

The Gin administrative theme has been added to Drupal core as the "Default Admin" experimental theme. The theme includes a new dark mode option.

While it is not yet actually the default admin theme, when it becomes stable it will replace Claro as the look of Drupal's backend. We encourage module maintainers to test their module's UIs and provide feedback!

Default Admin Theme in Dark Mode

Core maintainer team updates

Since Drupal 11.3 Andrei Mateescu was appointed as a provisional general core committer and is now a Content Moderation and the Workflows module maintainer too. Also Edward Wu was appointed as provisional release manager.

Various wonderful contributors also took our call for subsystem maintainership:

  • Moshe Weitzman is now a maintainer of the core CLI
  • Derek Wright stepped up to be a Content Moderation and core CLI maintainer
  • Kent Richards is a new accessibility maintainer
  • Max Pogonowski was added as a maintainer for Menu UI and the token system
  • Jürgen Haas and Sascha Eggenberger are maintainers of the new Default Admin theme
  • Chris Weber was added as a maintainer for Settings Tray
  • Stephen Mustgrave stepped up to maintain the Options module and Menu UI
  • Lucas Hedding is now a maintainer for the Image module and the Authentication and Authorization subsystem
  • Christian López Espínola is a new maintainer to the Language and Content Translation modules

We also thank maintainers that stepped down in this period:

  • Heather Brooke Drummond stepped down from their maintainer role on Breakpoint and Responsive Image modules
  • Brian Gilbert stepped down from his core mentoring role
  • Wim Leers stepped down from being maintainer of Drupal's CKEditor integration, Editor module, JSON:API module and REST module
  • Gareth Goodwin stepped down from maintaining the Umami demo

Want to get involved?

If you are looking to make the leap from Drupal user to Drupal contributor, or you want to share resources with your team as part of their professional development, there are many opportunities to deepen your Drupal skill set and give back to the community. Check out the Drupal contributor guide.

You would be more than welcome to join us at DrupalCon Rotterdam in September 2026 to attend sessions, network, and enjoy mentorship for your first contributions.

Drupal 12 is coming the week of December 7, 2026

Drupal 12 will be released with the upcoming Drupal 11.5 at the beginning of December this year. Drupal 11.5 will be a Long Term Support release with version 11 support expected until the end of 2028.

Read more...

Posted July 1, 2026 | 8:52 am

View all Drupal News...

e107 v2.3.12 Bootstrap CMS Released

[!CAUTION] v2.3.12 is a security release for sites on v2.3.11 or earlier. Upgrade from any 2.x at or below v2.3.11. If your site tracks the master branch, you are already past v2.3.12, so installing it would be a downgrade. v2.4.x is planned to be the next forward step.

[!IMPORTANT] Upgrade immediately. This release closes twenty-one security advisories outright and narrows a twenty-second, which needs one setting from you as well as the update.

AdvisorySeverityWhat it was
GHSA-f7x7-v438-qmf49.9 CriticalA member's post could attach a script to an ordinary image and run it for every reader, with nothing to click.
GHSA-48cx-ccvq-52mc9.9 CriticalAnything a member could write in BBCode could run script in another visitor's browser.
GHSA-9gr7-g6pw-52449.8 CriticalAnyone could sign in as a social-linked account, an administrator's included, with no password.
GHSA-m8v8-wc99-3h828.8 HighA member could give themselves a second way in that a password change does not revoke.
GHSA-pq2m-9gxf-64x98.8 HighA member who knew only their own password could write any column on their own account, including the two that make it an administrator.
GHSA-7v5h-vrhj-wjf58.1 HighOne read of the database forged a working login for every account on the site.
GHSA-vr9h-v6xq-4m358.1 HighThe automatic ban ships switched on and never counted a wrong password.
GHSA-c33m-2hph-47p47.4 HighComparisons in the login paths accepted values that were not the ones expected.
GHSA-pf37-7c5m-mpg37.2 HighAn administrator holding only the Languages permission could put PHP of their choosing into a file every visitor loads.
GHSA-22m8-h4gh-vfh36.8 MediumSigning in did not change the session identifier, so one known beforehand was known afterward.
GHSA-pw4f-4544-2mv26.5 MediumA handler meant only for the command line answered anonymous web requests as the main administrator.
GHSA-9qgj-v67f-r22q6.5 MediumAnyone holding a live session could set a new password without knowing the old one.
GHSA-396r-g8m8-w9xx6.1 MediumA crafted link to the File Inspector ran script in the browser of the administrator who opened it.
GHSA-3357-4wp5-w5fp6.1 MediumA contact form open to guests handed posted values back to the page as markup.
GHSA-cg88-cq8v-w6g65.4 MediumA page an administrator merely looked at could run database operations on their site.
GHSA-8xcj-7wmw-r9395.4 MediumA page anyone could link to deleted a member's private messages and rewrote their block list.
GHSA-72mc-5q6j-2fqq5.3 MediumOne anonymous request returned every user name on the site, banned and unvalidated accounts included.
GHSA-qj68-pgg7-hf3p5.3 MediumAnyone could publish FAQ entries without an account.
GHSA-f2q2-hchc-h3wx4.3 MediumOne member could vote on a star rating over and over and set the average to anything.
GHSA-vhf5-8cfh-jr224.3 MediumComments switched off on an item did not stop a member commenting on it.
GHSA-hwmh-m57x-w5h23.8 LowThe user manager did not apply the rules that protect administrator accounts to its batch route or to its single-row Unban and Delete controls.
GHSA-w24r-4r8j-vqgc3.7 LowA forged Host header was reflected into the addresses the site prints. Also needs a setting from you, see below.

The two worst need only a member account. GHSA-f7x7-v438-qmf4 and GHSA-48cx-ccvq-52mc between them reach every field that accepts BBCode: forum posts, comments, profile signatures. An administrator who views that content can install plugins, so the ceiling is a full site takeover.

Several need no account at all, so any internet-facing site could have been reached through them. The three worst are the passwordless sign-in as a social-linked account (GHSA-9gr7-g6pw-5244), the unlimited password guessing (GHSA-vr9h-v6xq-4m35), and the anonymous request that boots e107 as the main administrator (GHSA-pw4f-4544-2mv2). Look through Admin » Users for accounts you do not recognize, and for accounts holding administrator rights that should not.

Two can be narrowed short of upgrading. GHSA-3357-4wp5-w5fp reaches a browser allowed to see the affected contact form. Setting Contact page visibility to Members removes the exposure for signed-out visitors, but a signed-in member or administrator can still be targeted. To narrow it further, set the page to Nobody, and set the bundled contact menu's own visibility to Nobody in Menu Manager or remove it too, since that menu does not read the contact preference. Members-only has shipped since v2.3.2, so an older site is open to guests until someone changes it. GHSA-pf37-7c5m-mpg3 needs an admin account holding the Languages permission, so withdrawing it narrows the exposure. Neither issue can be hidden from the main administrator, who passes every class and permission check.

One is not closed by upgrading. GHSA-w24r-4r8j-vqgc needs a hostname from you, not a code change: a default install has never told e107 which hostnames it answers to, so it builds its addresses from whatever Host header arrives. Set siteurl to your site's full address, or list your hostnames under Trusted Hosts in Admin » Preferences. Either one arms the boot-time host check, so name every hostname you serve on: once e107 knows of one, a request arriving on a hostname you did not name is refused outright. Until you do, and while your site still takes new member registrations, a stranger can have e107 email somebody an account activation link that points at a host they picked.

[!WARNING] Some of these fixes change behavior you may be relying on. Each is deliberate, and each can stop something that worked in v2.3.11.

Do these before you upgrade.

  • Check that Trusted Hosts names every hostname you serve on. The boot-time host check now runs, and a request on a hostname you missed is refused outright. An empty list and a relative siteurl cannot lock you out, but a wrong entry in either can, and it takes the admin area with it. The way back in is the database: correct trusted_hosts or siteurl in the SitePrefs row, then delete S_Config_core.cache.php from your e107_system cache directory so the correction is read.
  • Export the Failed logins list if you keep it as a long-term record. The ban check now prunes that history to thirty days as it runs.
  • Regenerate your cron token if you have ever sent the Test Email in Admin » Schedule Tasks. That mail carried the token, so treat it as known.
  • Review the ban list for wildcard entries. An entry such as 10.77.66.* never matched anybody and starts matching after the ban files are next regenerated on v2.3.12. A wildcard whitelist row stays inert, as it was.
  • List your subdomains under Trusted Hosts if your site spans them. A valid security token no longer overrules a browser that says the request came from somewhere else.
  • Check Admin » Preferences for the user_tracking setting while it is still there. On a site installed before v2.3.0 where it was never changed, it reads cookie mode, and visitors can keep the old forgeable authentication cookie for up to thirty days, since only an explicit logout expires it. The old cookie can no longer authenticate anyone after upgrading. If you also want every browser to begin a fresh session under a new name, change Cookie Name in Admin » Preferences afterward.

These may behave differently afterward.

  • State-changing links now need a security token in their address: logging out, rating votes, social sign-in, deleting a private message, marking a forum read, much of the admin area. If logging out stops working, a theme, menu, or template is spelling out index.php?logout by hand and needs updating.
  • On PHP 8, a plugin that extends e107's routing or controller classes can stop the site loading, every page blank or naming the plugin's class in a Fatal error: Declaration of ... line. Rename that plugin's folder to get the site back, then send its author the one-line fix at For Developers » Changed.
  • *Five `LANCRONconstants are gone**, and a theme or plugin that prints one bare is a fatal error on PHP 8. If a page dies after upgrading, search your theme and plugin folders forLANCRON`; the five are named at For Developers » Changed.
  • The "Remember Me" checkbox is gone from the login form, and a browser still holding an old login cookie is signed out.
  • Eleven BBCode tags now filter or encode whatever a post writes into them. [table] keeps only the presentational attributes the tag was meant for and drops any others.
  • A news submission is stored through the same BBCode save pass as a comment or a forum post, so a tag's parameters are filtered on the way in and a submitter whose user class may post HTML keeps it, where the form used to strip every tag.
  • An [img] height, caption, or loading value set in the editor survives the save, where each used to be discarded every time.
  • Changing your own password in Settings now asks you to confirm it with your current password.
  • Wrong passwords count toward the automatic ban, and an address that exceeds the failed-login limit is banned for an hour. That hour arrives with Admin » Database » Update; until you run it, a wrong password is recorded and nobody is banned.
  • The SMTP connection test now needs the main-administrator permission, and the stored SMTP password is masked on the preferences screens.
  • Scheduled tasks triggered over a URL run as a guest, not as the first administrator. None of e107's own tasks cares; a third-party task that reads who is running it will behave differently.
  • On Apache, direct web requests into e107_handlers are refused where the server honors e107's .htaccess files. Core serves nothing from that directory directly, but a third-party public asset or endpoint placed there stops being served and must move.
  • A message sent through the contact form arrives as text, not as markup. A form whose senders were relied on to format their own messages loses that.
  • The Sign-in plugin no longer loads the Login menu's language file, so a custom signin_template.php written against the old LAN_LOGINMENU_* names loses its labels.

After upgrading, run Admin » Database » Update. This release changes the database: the failed-login ban gains a duration, the generic table gains two indexes, and session rows are re-keyed. Until you run it, those are pending.

On PHP 5.6 or 7.x, also check "Proof that a request came from this site" in Admin » Preferences after upgrading. Saving that screen while the recommended value was unset could silently select Off and stop e107 publishing security tokens. v2.3.12 fixes the form comparison but deliberately does not change a setting already stored as Off.

For Administrators below has the detail on each.

Highlights

  • Regression fixed: scheduled tasks run over a URL again, the only route most shared hosting panels and every external cron service offer. (#5919)
  • Regression fixed: avatars and thumbnails are visible again, after v2.3.11 began refusing the malformed image addresses e107 itself had generated for a decade. (#5893)
  • Busy sites stop serving the occasional broken page, now that every file e107 caches is written whole rather than emptied and then filled. (#5935)
  • A plugin or theme archive with a .. entry could delete e107_system, taking the cache, the logs, your saved backups, and the ban-list files with it. (#6119)
  • Private message attachments send again, silently dropped since v2.1.4 in 2017. (#5869)
  • Admin » Schedule Tasks now tells you how to schedule anything, writing the command, the crontab line, and the URL for you. (#5919)
  • The core paths covered by the test suite run without PHP 8.5 engine deprecations, including one that could print your server path at the top of every page on PHP 8.4 and later when deprecations were displayed. (#5951, #5952)

For Administrators

Added

  • Admin » Schedule Tasks has a Setup tab that writes your cron configuration for you. It inspects your server and offers three ways to do it, best first, each beside a Copy button: a web request for an external cron service, the PHP command line with the crontab or schtasks line, and a shell script. The Manage tab reports refused calls and links to Setup. (#5919)
  • The Download plugin's Local tab takes a typed path as well as a Media Manager pick. A file put in the downloads directory by FTP, which is how a 1.x migration or a restored backup arrives, has no Media Manager row and could not be attached to a download at all. What you type is resolved against the downloads directory, so a path that climbs out or names nothing is refused rather than saved. (#5737)

Changed

  • The "Remember Me" control is gone, and e107 no longer keeps your login in a browser cookie. The user_tracking preference is gone from Admin » Preferences and the authentication token lives only in the server-side session, so a browser still holding the old cookie is anonymous until its owner signs in again. The checkbox goes even from a site that had the setting switched off, since five of the eight places that drew it never consulted it. (GHSA-7v5h-vrhj-wjf5)
  • Changing your own password in Settings now goes through the confirmation page. It is the page an email change has always produced, so no theme template changes. Three smaller things changed with it: a replayed confirmation is refused; a submission carrying a validation error saves neither the new password nor an email address sent with it; and a confirmation displaced by a newer change in another tab is refused. An administrator setting somebody else's password is exempt. (GHSA-9qgj-v67f-r22q)
  • Wrong passwords count toward the automatic ban, and a failed-login ban now expires. ban_durations had no install default, so a failed-login ban was written with no expiry and never lifted. The counter now reads a rolling hour and failed-login bans get a one-hour duration, applied to existing sites once on upgrade and never overruling one you set afterward. The ban lands on the eleventh failure from one address inside the hour, successful sign-ins notwithstanding, and none is raised while that duration is missing or set to Indefinite. (GHSA-vr9h-v6xq-4m35)
  • Admin » Admin Password stores the password that was typed, and its form carries a security token. The screen compared its two boxes loosely, so 1e3 confirmed 1000, and it stored the first box, locking an administrator out of the account they thought they had set. On a site that allows email login it also stored a hash of the empty string as the email password. Its hand-written form now carries the token every other e107 form does.
  • The Failed logins list keeps thirty days where the automatic ban is on, and the generic table gains two indexes on upgrade. The ban counter reads that table on every failed login, and had to read every row ever recorded to do so. The check now drops history older than thirty days as it runs. (GHSA-vr9h-v6xq-4m35)
  • The boot-time host check arms on the hostnames you have declared, not on the shape of siteurl. An operator who listed their hostnames under Trusted Hosts and left siteurl relative was never checked against the list they had just written. (GHSA-w24r-4r8j-vqgc)
  • A numeric password must now be entered exactly. On a custom page the comparison read two numeric-looking strings as numbers, so 1e3 opened a page whose password was 1000. On PHP 8, where a trailing space no longer stops PHP reading a string as a number, 123 opened it too. Both stop working, and the same tightening applies to a plaintext password held by an alt_auth source. (GHSA-c33m-2hph-47p4)
  • Scheduled tasks triggered over a URL now run as a guest, not as the first administrator. A shell run is unchanged: user 1, every permission, under the name e107-cli. Over the web the run is an ordinary guest request, so your trusted-host list and the ban check apply; use the site address the Setup tab shows rather than localhost or an IP. (#5919)
  • A valid security token no longer overrules a browser that says the request came from somewhere else. The recommended setting accepts either proof, the browser's word or the token, and was read as "either will do", so a leaked token was accepted even where the browser had said the request came from another site. A browser that stays silent still falls through to the token. (#5914)
  • On PHP 5.6 and 7.x, saving Admin » Preferences no longer changes the unset, recommended request-proof setting to Off. Those PHP versions treated the empty option as equal to the option keyed zero, so the form marked both selected and the browser submitted Off. That stopped e107 publishing security tokens even though the administrator had changed no security setting. A site where Off is already stored stays Off until an administrator changes it. (98b4920)
  • Eleven BBCode tags now filter or encode whatever a post writes into them, instead of copying it into the HTML element unexamined. (GHSA-f7x7-v438-qmf4, GHSA-48cx-ccvq-52mc)
    • [table] is the one to check after upgrading. It rebuilds the tag from the attributes you wrote, keeping the presentational ones it was meant for and dropping anything else, so a table styled through an unusual attribute falls back to the default.
    • A link to anything but http, https, ftp, ftps, or mailto now renders as its own words. The old guard looked for javascript: alone and a tab inside the scheme walked past it, so [link] and [url] ask the URL encoder instead; a tel: or sms: link keeps its text and stops being a link.
    • The affected tags otherwise render as they did for ordinary content. [img], [textarea], and [stream] drop only the offending attribute; [alert] and [block] go through the class-attribute guard the other tags already used, with [alert] falling back to its default styling if its parameter holds whitespace; and [link], [email], [quote], and [flash] encode their values instead of listing them.
  • The core paths covered by the unit suite are quiet on PHP 8.5. Core code raised engine deprecations in nineteen categories there and on 8.6; the suite now reaches none. One could be visible when deprecations were displayed: on PHP 8.4 and later a Deprecated: Constant E_STRICT is deprecated line appeared twice at the head of every response, carrying your full server path. Scheduled tasks and command-line runs no longer bury their own output in deprecation notices. (#5951, #5952)
  • The Test Email in Admin » Schedule Tasks no longer mails your cron token. It dumps the server environment to the site administrator's address, and only one of its three tables was filtered. All three are filtered by value as well as by name now. (#5919)
  • Scheduled runs over HTTP are steadier. The token must match exactly and in constant time, a run is no longer cut off when the caller hangs up or by PHP's time limit, and a refused call is logged once an hour rather than once a call. (#5944)
  • The Documentation list in the admin area is ordered the same way on every server. It was sorted using the server's language settings, so the order depended on which locales the host had installed. (#5951)
  • Theme options no longer report "saved" when the write failed. Admin » Theme Manager printed the green success line whatever the preference write returned, so a database refusal produced "Theme options saved" beside "Settings not saved." on one screen. A failed write now says so once, with the reason in Admin » System Logs, and a theme that declares no options no longer forces a write that had nothing to store. (#6018)
  • Three dozen state-changing links across e107 now carry a security token, and refuse a request without one. e107's cross-site request protection treats only a POST as state-changing, so a link that acts on your site has to protect itself, and most did not. Every link e107 renders carries the token, so the ordinary route is unchanged; a bookmark or a hand-built link shows a refusal instead of acting. The reported case is Database Utilities; the rest is the same audit carried across the product. (GHSA-cg88-cq8v-w6g6)
    • Logging out is the one most likely to affect you. ?logout on any page has been the e107 idiom since v1, so a theme, menu, or template that spells it out by hand leaves the visitor signed in with an error on the page. Both bundled themes and every core logout link were updated.
    • Rating votes and social sign-in. The caret-separated rate.php ballot and index.php?provider= both acted on a bare address. The address a provider returns to is unchanged, so nothing is re-registered with Facebook or Google.
    • Private messages, newsletters, and the forum: deleting a message, blocking or unblocking a member, unsubscribing from a newsletter, and marking a forum read. The forum's v1.x upgrade page refuses a tokenless request outright, POST included, and stops deleting six plugin files on every load.
    • The SMTP connection test now needs the main administrator, where any account holding the mailout permission could run it before. The stored password renders as dots on both preference screens, and leaving the field untouched preserves it.
    • The core database update page needs a token too, and answers a refusal with 403. e107_admin/e107_update.php reached the update routines from a bare address, so an image tag on a page a main administrator visited flushed the system cache and re-ran every installed plugin's setup file. The page's own form still submits.
    • Two more paths are confined as hardening rather than fixed vulnerabilities: the Sync with Github route, and the Feature Box legacy renderer, which can no longer include a file outside its own template directory.
  • A wildcard entry in the ban list matches again. 10.77.66.* was stored as typed while the check compares an encoded form of the address, so it sat in the Banlist looking live and stopped nobody. Trailing whole-octet IPv4 wildcards are encoded now, on ban rows alone: a wildcard whitelist row stays inert. It takes effect the next time that screen rewrites the ban files, so open Admin » Users » Banlist and save one entry after upgrading. (#6114)
  • The Sign-in plugin ships its own language strings. It borrowed twelve constants from the Login menu, a separate plugin, so deleting that plugin from disk took the sign-in form down. Eleven LAN_SIGNIN_* strings replace them with identical text; the twelfth, the password field's label, now comes from core's LAN_PASSWORD and reads "Password" rather than "Password: ". (#5719)

Fixed

  • [Security] A BBCode parameter could name an HTML attribute, or escape its quotes. [textarea] and [stream] emitted each parameter as an attribute name, where no encoding protects it, so a member could write an event handler that fires for every reader with nothing to click. [img], [alert], and [block] let a parameter escape its quotes to the same end. All five now filter or encode each parameter where they render it, which is the only boundary that reaches content stored before the upgrade. (GHSA-f7x7-v438-qmf4, GHSA-48cx-ccvq-52mc)
    • The image renderer escapes the attributes it writes. The routine behind [img] pasted id, class, style, title, loading, and the width and height overrides into the tag as given, for every caller and not only the BBCode.
    • A news submission is saved through the BBCode pass. The Submitted News form stored what was typed without it, so that route needed no bypass at all, and the payload rendered in the admin panel's preview of the queue.
    • The save-time pass runs on a post that mixes HTML with BBCode. e_parse::isBBcode() answered false for any text carrying something shaped like , so a single tag anywhere in a submission skipped every save-time BBCode filter. It answers on the BBCode alone now. Stored rows are untouched, and the next save of such a post is filtered like any other. (#6265)
    • [img] keeps a caption and a loading value through the save, as it now does a height, and the caption reaches the reader as it was typed rather than with its apostrophes spelled out.
  • [Security] Five BBCode tags no longer pass what was typed inside them into the page unescaped. [link], [email], [quote], [table], and [flash] each wrote the text after the tag name, and for [email] and [table] the text between the tags as well, straight into an HTML attribute or an inline script, so a member could attach an event handler, or with [flash] inject an element outright. Ordinary content renders as before; [table] is the exception, above. (GHSA-48cx-ccvq-52mc)
  • [Security] A login request can no longer select e107's internal OAuth mode, and a profile update can no longer set the field it matches on. The posted autologin field reached the login handler, which read provider out of it as an internal mode. That mode matches on the account's social-provider identifier, a name rather than a secret, and returns success without checking a password: that identifier posted with an empty password signed you in as that account, even with social login switched off. The identifier was member-editable, a second credential no password change revokes. (GHSA-9gr7-g6pw-5244, GHSA-m8v8-wc99-3h82)
  • [Security] A read of the database no longer forges a working login for every account. The authentication token was the user id and a plain hash of the stored password hash, with no secret mixed in, so reading the user table computed a valid token for any account. In session mode, the default, the session table stored each identifier verbatim, so one read of it was a set of live cookies. Cookie-mode authentication is removed and stored identifiers are hashed. Live sessions survive the upgrade; a browser holding the old authentication cookie is signed out. If you think your database has been read, empty the e107_session table after upgrading, because an identifier captured before it works until its row expires. (GHSA-7v5h-vrhj-wjf5)
  • [Security] The automatic ban counts wrong passwords. e107 ships the ban switched on with a limit of ten, and it counted an unknown username or an unactivated account but never a wrong password, so guessing the password of an account that exists was neither recorded nor banned on either login form. A whitelisted address was also reported as banned while carrying on signing in, and the row recording an automatic ban was never written at all. With alt_auth installed, a local password that misses and then authorizes through the fallback takes its ban back with it; the member used to be signed in and locked out on their next request. (GHSA-vr9h-v6xq-4m35)
    • The activation-resend form's separate password check enters the same failure path now. It previously allowed unlimited guesses against an unactivated account without recording or banning them, and a correct guess could move the activation email to an address the visitor supplied. A correct password stored in e107's legacy MD5 format is accepted too; that check had mistaken the replacement hash returned for a valid old password for a failure. (e1097e6, 641d761)
  • [Security] The language file editor escapes what it writes into the PHP it generates, and writes only inside e107's language, plugin, and theme directories. Admin » Language » Tools pasted request values into that source, so a value carrying a quote could close the statement and append code of its own; the locale was written with no quotes at all. The file is loaded on ordinary page views, so the code ran for every visitor rather than staying behind the admin login, and the path was as open, the file being edited coming from the request. The regenerated header no longer carries the saving administrator's display name, which could end the comment it sat in and run the same way. (GHSA-pf37-7c5m-mpg3)
    • The editor also reads escaped quotes and trailing whitespace without damaging the phrase. Its reader could stop at an escaped quote or match a closing quote of the wrong kind, so saving the file again could truncate or otherwise change a translation the administrator had not edited. It now matches the quote that opened the phrase and preserves whitespace at the end. (508dc47, f12d76c)
  • [Security] Signing in changes the session identifier. e107 let an anonymous visitor's identifier become their authenticated one unchanged, so anyone who knew the value beforehand knew a signed-in session's value afterward. On a default install that identifier is the credential, not a handle on one. The only visible difference is that an admin screen left open from before a sign-in or a password change has to be reloaded before its inline edits are accepted again. (GHSA-22m8-h4gh-vfh3)
  • [Security] A script that declares itself command line only is refused over the web. Neither half of e107's guard for this did its job, so an anonymous web request to the bounced-mail handler booted e107 as the main administrator. From there it appended to a log file under e107_system and overwrote the cached timestamp Admin » Mail reads, once per request, with nothing to stop it. The caller could not supply the message text, so it could not mark anyone's mail as bounced or make the site send mail. (GHSA-pw4f-4544-2mv2)
  • [Security] Changing your password in Settings requires the current password. Settings withheld an email or login-name change until the holder re-entered their current password; the password change itself never asked. Anyone holding a live session could set a password they knew, lock the owner out, then satisfy the email confirmation with the password they had just set, and sending both changes in one request waived that confirmation too. The prompt now applies on every site, including those with no email login and those on the oldest password hashing, where the old checks never fired. (GHSA-9qgj-v67f-r22q)
  • [Security] A member could write any column on their own user row, including the ones that make an account an administrator. The confirmation stage that guards an email change sent the pending change out to the browser and rebuilt it from whatever came back, and both checks on that round trip did nothing; one had never worked since 2016. A member who knew only their own password could post that stage directly, name any set of columns, and be saved as written, without going near the settings form. (GHSA-pq2m-9gxf-64x9)
  • [Security] The user manager applies the rules that protect administrator accounts on every route that writes them. Admin » Users refuses to rewrite an administrator's account without the "Modify Admin perms" permission, and refuses to ban the main administrator at all. Neither applied on the batch route, nor on the six single-row controls any user-management permission could reach by posting the trigger: Ban, Unban, Delete, Verify, Reqverify, and Resend. A delegated administrator could ban or delete the main administrator, sign another one out everywhere, or, where the signup password option is empty, have Resend replace their password; unbanning does not restore a working login. All seven now answer to both rules. (GHSA-hwmh-m57x-w5h2)
    • The user export leaves out the password hash and the session key. Ticking rows on Admin » Users and choosing Export wrote both columns into the file, and the export is exempt from the administrator rule because it only reads.
  • [Security] Database Utilities asks a state-changing link to prove where it came from. Every mode was dispatched straight off the query string, behind the main-administrator check alone, and the six that act needed nothing more. A main administrator who loaded an attacker's page ran, from something as quiet as an image tag, an optimize over every table, a system cache flush that re-executed every plugin's setup file, a recursive permissions change, a registry rebuild, and a full database dump. (GHSA-cg88-cq8v-w6g6)
  • [Security] A member can only vote once on a star rating. The duplicate-voter check was broken twice over: the first person to vote on an item could re-vote without limit, and everyone else could bank one vote per rating value. A single member could drive a displayed average anywhere they liked, the widget rendering read-only while the endpoint behind it went on accepting votes. Tallies already inflated stay inflated. (GHSA-f2q2-hchc-h3wx)
  • [Security] Authentication values are compared byte for byte and in constant time. About one MD5 digest in 340 million takes a form PHP reads as the number zero, and where the server computed one of those the check then accepted any value PHP also read as zero, so there was nothing for an attacker to compute. Every comparison in core that guards a login or a stored credential now compares byte by byte. (GHSA-c33m-2hph-47p4)
  • [Security] The site's own addresses were built from the Host header the visitor sent. e107 puts them in its canonical link, its OpenGraph tags and its resource URLs, and the check that should have refused an unrecognized hostname almost never ran. It now runs whenever you have told e107 a hostname of its own; if you never have, the note at the top of these release notes says what to set, because upgrading alone does not close this for you. (GHSA-w24r-4r8j-vqgc)
  • [Security] A contact form open to guests no longer hands posted values back to the page as markup. The message a visitor typed was written into the form's text box as it arrived, the email address into an attribute it could break out of, and the assembled page was parsed again, so a shortcode typed into any field was expanded too. An install from v2.3.2 or later did not expose signed-out visitors by default, because Contact Form Visibility has shipped set to Members since then; signed-in members and administrators who could see the form remained exposed. An install from an earlier release is open to guests unless someone changed it: the preference shipped as everyone from 2015 to 2022, did not exist before that, is treated as public when absent, and no upgrade sets it. The bundled contact menu shows the same fields and does not read that preference, so set its own visibility in Menu Manager or take it out. (GHSA-3357-4wp5-w5fp)
  • [Security] Saving the Online menu configuration no longer files your session's security token as a preference. The screen copied every field the browser posted onto the shared menu preference row, and since v2.3.10 e107 injects a hidden security token into every form it renders. Each save stored the live token and wrote it into Admin » System Logs, where any administrator who can read the log could take it. (#6084)
  • [Security] The File Inspector no longer writes its scan identifier into the page unchecked. The identifier arrived from the address bar and went into an HTML attribute as it stood, so a link sent to an administrator could run script in their session. Only administrators who can reach the File Inspector were exposed, and only by opening the link. (GHSA-396r-g8m8-w9xx)
  • [Security] Deleting a private message, or changing your block list, asks the request to prove where it came from. Four addresses acted on a bare link, so a page a member merely visited could empty their inbox or rewrite who they had blocked. Marking a message read stays a plain link, deliberately: the one in notification mail depends on it. (GHSA-8xcj-7wmw-r939)
  • [Security] The member typeahead answers only where the member list is public. Two lookups, one in Private Messaging and one in core, replied to anyone who asked, and a keyword of punctuation matched everything, so a single request returned every account on the site, banned and unvalidated ones included. (GHSA-72mc-5q6j-2fqq)
  • [Security] Submitting or editing an FAQ requires the permission the form checks. The FAQ plugin tested the permission when it drew the form and not when it saved, so anyone could post entries straight to the handler. Sites that never installed the FAQ plugin were not affected. (GHSA-qj68-pgg7-hf3p)
  • [Security] Switching comments off on an item now stops comments on it. The rule lived in only one of the two paths that save a comment, so the other accepted posts on news items, custom pages, downloads and profiles whose comments were closed. (GHSA-vhf5-8cfh-jr22)
  • Regressions from v2.3.11.
    • Regression fixed: scheduled tasks can be triggered over a URL again. v2.3.11 refused every call that arrived over the web, so a crontab that had worked for years ran nothing while logging a refusal a minute. (#5919)
    • Regression fixed: thumbnails and avatars resolve again. e107 has always rendered thumbnail addresses that the request layer then mangles, and v2.3.11's stricter thumbnailer turned a silent fallback into a visible 403 Bad URL. (#5893)
    • Regression fixed: outbound requests can reach the second address of a hostname. v2.3.11 pinned each fetch to the first resolved address, so on a server without cURL a dual-stack hostname whose IPv6 address sorted first failed outright. (#6054)
    • Regression fixed: sending an attachment no longer walks every attachment directory on the site. v2.3.11 made every private message with an attachment, and every forum post whose form drew the field, re-check thousands of member directories for no gain. (#6160)
  • A busy site no longer serves half-written cache files. e107 wrote each cached file by emptying it and then filling it, so a request that read one in between got an empty or partial file. Which cache lost the race decided the symptom, which is why this has been reported for years as unrelated one-off glitches. Every cache e107 rewrites on a live request now goes through a temporary file and a rename, and the page-block cache's separate read-side race was narrowed with it. (#5935, #5917)
  • A plugin or theme archive with a .. entry no longer deletes e107_system. Uploading a zip whose first entry sits above the root made the unpacker resolve its destination to the parent of e107's temporary directory and remove it recursively, taking the cache, the logs, the saved backups, the import folder, and the ban-list files. Four upload failures that all reported "Couldn't detect the root folder in the zip" now name their reason. (#6119)
  • Menus, navigation, and site links.
    • The Login menu is working again, in five ways. Saving its configuration no longer empties the shared menu preference row, which had been reverting the banner, comment, online, last-seen, and forum menus to their defaults since 2014. Additional Links and plugin statistics are offered again, absent since December 2020. The screen shows what you just saved, the statistics sit inside the menu rather than beside it, and the username box has its placeholder back on username-only sites. (#6044, #6048, #6069, #6083, #6096)
    • Navigation built from site links could exhaust PHP's memory and take the page down. The site links a fresh install creates were enough to make a renderer call itself with the menu it was drawing, so a theme using {SITELINKS} or {SITELINKS_ALT} went blank. Neither bundled theme does. (#6065)
    • A site link keeps the address you saved when its search-engine-friendly route cannot be built. Six places overwrote it with a generated address that a plugin missing from the URL registry does not have, so the link pointed at the site root and its admin field came up blank. Each of the six now falls back to the address on the row. (#5783)
    • A navigation menu pointing at an empty link category draws nothing instead of an empty box. A default install ships links in two categories only, so a menu placed anywhere else is the common case. (#6112)
    • The News Grid menu's Featured setting takes effect. It was saved under a field name one letter short of the one the renderer reads. Existing menus keep the old key, so save each once in Menu Manager after upgrading. (#5955)
    • A Feature Box menu renders again when its category preference is empty. The plugin seeds one category name and the code fell back to a different one, so the menu asked for a category that did not exist. (#5957)
    • The Menu Manager opens again on a theme whose layout uses {FEATUREBOX}. Its preview printed a name only the Feature Box plugin defines, which is fatal on PHP 8 when that plugin is inactive. (#5956)
    • Two more link fixes. A plugin installed from the plugin manager lands in the same URL state as one installed at setup; and the bundled _blank sample plugin's navbar link points at the page it ships rather than a file it does not contain. (#5790, #6224)
  • The front end.
    • Login, signup, search, user settings, password reset, the members-only page and the Users Online menu render on a theme that supplies its own templates. e107 chose between the old and new template shapes by reading a constant the loader does not set, so a theme's own template was passed over and the page fell back to core markup or drew nothing at all. (#6017)
    • The Users Online page shows who is online. It blanked its own template variables before loading the template, so the page drew a heading over nothing, as it had since 2019. Its profile links are built through the URL handler now. (#6108, #6107)
    • The member list shows members again, under both URL configurations. The record count arrived as zero, so every page reported that the site has no registered members, and the paging bar divided by that zero. (#6002)
    • A mistyped address answers with the error page instead of a fatal error. e_PAGE is defined after the 404 page has been rendered, so a plugin's shortcode file read a constant that did not exist yet and every unknown URL ended in a fatal on PHP 8. (#6024)
    • The news page survives a junk ?page= value, which was an uncaught error on PHP 8, so a scanner or a mistyped link took the page down. Only sites whose News pagination preference was changed are reached. (#6110)
    • [email] and [link] survive the "Make URLs clickable" setting. The clickable pass ran before the BBCodes and handed them an anchor where they expected an address, so [link] lost the address and [email] produced a link inside a link. It runs after them now. (#5954)
    • Tabs switch again on a Bootstrap 4 theme. Bootstrap renamed the state class in version 4 and the data attributes in version 5, and e107 applied one boundary to the other. Both spellings travel on the same element now. (#5990)
  • The forum, private messages, the chatbox, and the contact form.
    • Private message attachments are sent again. The attachment branch was gated on a field the compose form has never posted, so since v2.1.4 the file was uploaded, the message was delivered without it, and neither party was told. (#5869)
    • A private message notification email names the member who sent it. It took the name from whoever the current request belonged to, so one sent from a scheduled task named e107-cli or nobody. (#5944)
    • The chatbox stays on the page you were reading. Its form actions were built from the underlying PHP script, so posting from a search-engine-friendly page landed the visitor on /news.php. (#5614)
    • The AJAX chatbox validates before it posts. Pressing Send bypassed the browser's own check on the message box, so an empty post made a wasted round trip. (#5616)
    • The first click on a smiley inserts it. The emote panels in the chatbox and the private message composer did nothing until the visitor had clicked into the message box first. (#5613)
    • A message sent through the contact form carries the sender's address. It traveled only as a Reply-To header, which many mail clients never show and which is lost when the message is forwarded. The From address stays the site's own, so the site's mail still passes SPF. (#5980)
    • The contact form stops drawing a second CAPTCHA over a plugin's own. e107 looked for the field name its own renderer emits, which a replacement does not use. (#6014)
    • The SMF importer files JPEG and GIF attachments as pictures. One condition tested the same extension twice, so everything but PNG and one spelling of JPEG arrived as a download link. WebP is accepted too, and an import already run is not reclassified. (#6134)
    • The forum's Quick Reply button says "Post a quick reply", and Post Reply keeps what you typed. With the Rich Text Editor selected the two read alike, and clicking the wrong one dropped the text; it is carried into the full reply form now. (#5647)
    • A theme that defines only some forum icons gets the rest from the plugin. The loader was all or nothing, so a partial forum_icons_template.php left about two dozen IMAGE_* names undefined, which is fatal on PHP 8. Such a theme now renders the plugin's default icon where it drew nothing. (#6209)
    • A forum attachment is refused when the deny rule over its directory cannot be written. Four places stored the bytes whatever the answer, so on a host that refuses the guard file the upload landed with nothing but its random name protecting it, and nothing was logged. (#6171)
    • A post that pastes a YouTube player keeps its text. The [youtube] save path for a pasted embed replaced the post with a placeholder, printed its parse into the save response, and dropped the privacy-domain setting; a pasted player now round-trips. (#6265)
  • The admin area.
    • Editing a member's user classes from the list no longer deletes one. The tick list held only the classes the column was configured to offer, and saving the cell wrote the ticked boxes over the whole field. Admin » Users omits the built-in Members class while Quick Add adds it to every account, so that combination silently dropped Members. (#5779)
    • Editing user classes from the Users list obeys the rules about which classes you may manage. Only the dedicated Set user class screen refused a class whose manager class the administrator does not hold; the inline pencil editor, the full edit form, the batch menu and Quick Add User did not check at all. All four apply the rule now, refusing and logging the attempt. The main administrator is unaffected, and a class you may not manage is no longer dropped by saving the editor.
    • The "Add All" and "Clear All" user-class batches work for administrators other than the main one. The shared guard refused every class rather than granting it, so "Add All" answered Update failed and did nothing, while "Clear All" read the empty list as no list at all and emptied the whole User Class column on every ticked row. Both now apply the classes you may manage and name the ones they left out.
    • Deleting a preference no longer takes the front end down with no way back. Removing url_config made every address carrying a path fail on PHP 8 while the front page kept answering. Admin » Database » Update puts the default back. (#5928)
    • A settings screen that cannot save now tells you why instead of ending in an error page. The screens that save this way include URLs, User Classes, Ban List, Emoticons, Meta Tags, Notifications, Search, and Themes. (#5921)
    • Saving ban messages or durations, and removing expired bans, no longer end in a blank page. Three calls in Admin » Users » Banlist went to a logging helper deleted in 2020, so each died after the work had been committed. (#6051)
    • An empty database statement is refused and reported instead of ending the request. The one place on this branch that can produce one is the character set conversion tool in Database Utilities. (#5904)
    • A failed database operation reports its reason again. Six live assignments spelled the two error-message properties differently from the way the class declares them, so a backup or a row copy that declined reported nothing at all. (#5951)
    • Admin » URL Configuration loads again on a site with the Gallery plugin installed. Its address profile read labels from the plugin's own language file and never loaded it, which is fatal on PHP 8. The alternative rewrite profile still misses that file, so a site using it will still fail to load Admin » URL Configuration » Settings. (#5917)
    • Previewing a theme no longer takes the theme manager down. Labels were read from the theme the request was rendering in rather than the one on screen, so the wrong language file loaded and the page was fatal on PHP 8. (#5996)
    • A failed "Sync with Github" shows the reason instead of a blank page, and gets three times as long to download. These archives run to tens of megabytes, and the old 40 second budget demanded a sustained rate many connections cannot hold. (#5893, #5620)
    • Outbound requests stop refusing hosts your server can reach. The guard resolved hostnames with PHP's own DNS functions, which query the network directly rather than asking the operating system, and refused the address when nothing came back. (#6012)
    • Admin > Schedule Tasks > Setup no longer fills the PHP Errors panel on a host with open_basedir set. It probes absolute paths for a control panel and a PHP binary, most of them outside every allowed prefix on such a host. (#5991)
    • The PHP Errors panel stops reporting diagnostics core deliberately silenced. Anything a caller had silenced with @ was collected and printed anyway, which the atomic cache write made visible: every ordinary cache miss began reporting a failed stat. (#5992)
    • Admin > Users > Avatars deletes the file it names, and measures the right limit. It passed a thumb.php address to the delete and to the size check, so a checked image was cleared from the account and left on disk while every avatar counted as missing, and the height report read the width preference. (#6023)
    • The Credits page no longer restyles the rest of the admin area. It registered four bare element rules, for body, p, a, and a:hover, into the shared inline stylesheet the admin header emits. (#5981)

For Developers

Added

  • e_parse::toJsString() encodes a value for a JavaScript string literal. It returns the quoted literal, its own quotes included, so interpolate the result bare. Quotes, apostrophes, angle brackets, and ampersands become hex escapes, so it is safe inside an HTML attribute carrying script too. Encoding failure returns an empty string literal. (5b27db3)
  • e107::writeFileAtomic($file, $data, $mode = null) writes a file so a concurrent reader gets the old contents or the new, never a partial one. It writes through tempnam() in the target's own directory and rename()s into place, falling back to file_put_contents() where either step is impossible, so a true return means the file holds the data, not that the write was atomic. Overwriting resets mode and owner, and the read side is uncovered. (#5935)
  • e_form::copyable() renders a block of text with a Copy button. It takes the text and an optional label, and emits its own script and styles once per page. New LAN_EFORM_COPY and LAN_EFORM_COPIED constants back it. (#5944)
  • e107\Reflection\ReflectionProperty and e107\Reflection\ReflectionMethod make private members readable across the whole supported PHP range. PHP 8.1 stopped requiring setAccessible() and 8.5 deprecates the now-empty call, while 5.6 through 8.0 still require it, so these two subclasses make the call themselves only where it is needed. (#5951)

Changed

  • Nullable type hints are gone from eleven core method signatures, and a plugin that overrides five of them with the old signature will fatal on PHP 8. eRequest $request = null is the only nullable spelling PHP 5.6 accepts and the one PHP 8.4 deprecates, so it had to go. The five that fatal are eFront::dispatch(), eDispatcher::dispatch(), eController::run(), eUrlConfig::parse(), and e_session::fetchMetadataReachesUs(). The fix is one line: delete the eRequest, eRouter, eResponse, or array hint from the override. Watch eUrlConfig::parse(), which a plugin shipping its own url/url.php overrides. (#5951, #5930)
  • The engine deprecations the unit suite raised on PHP 8.5 and 8.6 are cleared, one commit per deprecation. Nineteen categories, from dynamic properties and (integer) casts through setAccessible(), implicitly nullable parameters, E_STRICT, and strptime(). The suite does not reach everything the tree holds. Two are replacements rather than respellings: Latin-1 conversion goes through iconv() alone, and e_parse::cleanHtml() now substitutes ? for invalid UTF-8 where it produced U+FFFD. (#5951)
  • Dynamic properties are gone from four places, and two of them a third party could be leaning on. e107plugin::execute_plugin_method() no longer assigns version_from onto a plugin's setup class, which should call e107::getPlugin(), and e107::__get() memoizes into a static array, so $e107->tp after e107::destruct() returns the object rather than null. Six classes now declare the properties their constructors assign, so a subclass declaring one with narrower visibility fails with an access-level error. (#5951)
  • Cookie-mode authentication is gone, and five login shortcodes with it. LOGIN_TABLE_REMEMBERME, LOGIN_TABLE_AUTOLOGIN, and LOGIN_TABLE_AUTOLOGIN_LAN go from the core login form; {LM_REMEMBERME} and {SIGNIN_REMEMBERME} go from the Login menu and Sign-in plugins. An unresolved shortcode renders empty; the language constants stay defined, since a removed constant printed bare is fatal on PHP 8. The user_tracking row is no longer seeded on a fresh install, so third-party code reading it without varset() warns there; on an upgraded site it survives reading cookie, so code branching on it takes the branch for a feature that is gone. session_set() keeps its value in the session and ignores its $expire, $path, $domain, and $secure arguments, so a value parked across visits is lost when the session ends. e_session_db::_sanitize() is now static, which is fatal for a subclass that overrides it as an instance method. Session rows are re-keyed to a digest of the identifier, which raises a pending core update on essentially every site. (GHSA-7v5h-vrhj-wjf5)
  • userlogin::login() no longer honors 'provider' in its $autologin argument, and user_xup is out of the member-editable field list. The provider mode travels on an instance flag only userlogin::loginProvider() sets, and class2.php casts the posted value to an integer, so no mode can be selected from a request. The documented 'signup' value still works, and social signup and login write user_xup server-side without consulting the field list. (GHSA-9gr7-g6pw-5244, GHSA-m8v8-wc99-3h82)
  • The user-settings confirmation form no longer round-trips the pending change through the browser. updated_data, updated_key, updated_extended, extended_key, and the private getValidationKey() in usersettings.php are gone; the change is held in the session and the form carries an opaque handle. A confirmation the server is no longer holding anything for now says so instead of reporting success, and the confirmed values are no longer passed through filter(..., 'str'), which had been double-encoding plain fields and flattening cleanHtml() output on rich-text ones. UserHandler::hasReadonlyField() has also been repaired. It answered false for any field set it could not iterate, which is the one answer its own documentation promises never to give; it now reads an array or a Traversable, refuses anything else rather than reporting no restricted field, and recognizes a list of field names as well as a keyed set. user_class remains writable, because user settings already filters it through the classes the member is allowed to edit. (GHSA-pq2m-9gxf-64x9)
  • An admin list batch must name a field the screen declares batchable. e_admin_controller_ui::_handleListBatch() asked only that the posted column be a declared field; it now also requires the 'batch' flag the dropdown is built from, and refuses a field declared 'data' => false. A plugin admin UI that posts a batch trigger for a field it never marked 'batch' => true now silently does nothing. (#6074)
  • An entry script that sets $_E107['cli'] is refused when the request arrived over HTTP. The shared guard tests the shape of the request, as cron.php already did, rather than a User-Agent header and the debug flag. The debug clause is deleted rather than corrected: nothing has read e107_config.php that early. (GHSA-pw4f-4544-2mv2)
  • Apache is also told to refuse every direct request into e107_handlers. Core fetches nothing from that directory over the web, so a default installation loses nothing. A third-party public asset or endpoint placed there stops being served on a host that honors e107's .htaccess files and must move elsewhere. The PHP bootstrap guard above remains the protection on servers that ignore the file. (064476a)
  • A scheduled task must no longer assume who is running it. cronScheduler's docblock states the contract: a task runs as the first administrator from the command line and as a guest over HTTP, so it must not read ADMIN, USERID, USERNAME, or USERCLASS_LIST, and must not assume e107::redirect() is a no-op. cronScheduler::run() now takes a $via argument, so a subclass overriding run() with no parameters fails to load; nothing in the tree does. (#5944)
  • *Five `LANCRONconstants and one help file are gone, and about forty constants are new.**LAN_CRON_13,LAN_CRON_14,LAN_CRON_15,LAN_CRON_16, andLAN_CRON_60go, withe107_languages/English/admin/help/cron.php`. A language pack that translates the old names needs updating, and a theme or plugin that prints any of the five bare is a fatal error on PHP 8. (#5944)
  • Three places that turn stored or posted text into a filename or an identifier are confined. (804197f)
    • A shortcode name is checked before it is used as a filename. Names must match ^[a-z0-9_]+$, and one that does not is left in the page as written. Members reach this parser, because toEmail() turns shortcode parsing on by default.
    • The plugin builder no longer takes identifiers for generated code from posted keys. Identifiers must look like identifiers or they are dropped, and values go through var_export().
    • email.php narrows its plugin source parameter, as print.php already did, differing only in that it also permits a hyphen.
  • e_jsmanager encodes every asset URL it prints and packs its registry through one method. A path or media value registered by a caller reached a or attribute unencoded, and one carrying the #|# separator the registry joins on could shift the fields of its own record. Reaching either needs a permission that already grants code execution, so this is hardening rather than an advisory. (cceda40, ac2f645)
  • Two hardening changes, neither of which alters a public signature. The legacy CRUD methods (select(), count(), delete(), fields(), insert(), update(), replace(), db_UpdateArray(), db_FieldList()) return false, without throwing, and record error number -1 for a table name outside [A-Za-z0-9_]+, on both drivers, so a plugin that passed a dotted db.table or a backticked name now gets false. And users_admin_ui::beforeUpdate() filters user_class through checkAllowed(), so every route into the model applies the userclass_editclass rule, vetting a withdrawal like an assignment.
  • e_db_pdo::close() now releases the connection, and the last result set with it. A PDOStatement holds a reference to its connection, so nulling the handle left the server connection alive whenever a query had run. Nothing fetched before close() is readable after it. The mysqli driver already behaved this way. (#5935)
  • e_pref::save() honors its own "no messages" argument. Both error branches printed the raw mySQL error #NNNN on screen whatever the caller asked for. Around two dozen core callers pass false, so a failed preference write in the update routines, the plugin handler, Menu Manager, Search, or the URL configuration now reports to Admin > Logs. (#6018)
  • A theme configuration field absent from the submission is stored as an empty value of its own type. null used to be stored, which is invisible to isset(), so a theme calling count() or in_array() on getThemePref('x') took the page down on PHP 8. A field the form posts as name[] now stores an empty array, everything else an empty string. If your theme relied on getThemePref('x', 'fallback') returning the fallback for an unticked box, it now gets ''. A theme's values also save into its own preference row. (#5995, #6036, #6133)
  • The test suite has separate dependency locks for newer and older PHP releases. The single pinned lock could not be installed above PHP 8.3, so from 8.4 upward the suite never reached its first test. The default lock is resolved for PHP 8.1.33 and carries Codeception 5.2.2 with PHPUnit 10.5.64; the PHP 7.4 and 5.6 locks carry Codeception 4.2.2 with PHPUnit 9.6.36 and 5.7.27 respectively. The harness installs the newest committed lock its PHP can satisfy. (#5950)
  • Continuous integration and the test harness were reworked, and the Code Climate integration is gone. The unit workflow's hand-rolled provisioning is replaced by e107-tests up and e107-tests ci-unit, so a CI failure reproduces locally with those two commands. The unit matrix no longer measures coverage nothing consumed, which was most of its wall clock: the PHP 5.6 cell falls from about sixteen minutes to two. (#5884, #6180, #6221, #5940, #6270)
  • Test-suite changes worth knowing if you run it. AdminConfirmTokenTest is gone: it matched source against a registry pinned by file and line, so unrelated edits failed it, and 0038_AdminConfirmTokenCest covers the same ground against the real forms. The entry-script sweep now runs each script in its own process and fails on a warning or a notice. themeHandlerTest stops leaving theme preferences behind, which had been failing a later case in a shuffled run, and .gitignore now covers the e107_config.php.bak the harness writes while a test site is up, which a broad git add could stage with the database password in it. (a6e54a1, #5917, #6228)

Fixed

  • Eight reads of array keys that need not be present are guarded, clearing the PHP 8 warnings they raised. They sit in the search preferences, File Inspector, Mailout, the user model, the page address builder, and Admin > Language > Tools. Nothing rendered changes, and none of it was visible on a default site: e107's own error handler discards warnings, so these surfaced only with ?debug= set. (#5886, #5917, #6109)
  • Four more reads that are fatal on PHP 8 rather than merely noisy. sitelinks::get() called count() on a missing submenu bucket in link display mode 3; e_parse::toAvatar() multiplied an empty string when the documented hd option was used with no explicit height; four forum templates read IMAGE_post2 and IMAGE_e as barewords at include time; and language::$_select_array was read before it was declared. None is reachable from core or a shipped theme. (#6073, #6060, #6086, #6085)
  • e_db::getLastErrorNumber() returns a MySQL error number on the PDO driver. It returned PDOException::getCode(), the SQLSTATE: '23000' where the mysqli driver returns 1062. PDO is the shipped default, so every caller comparing that value against a MySQL error code failed silently on nearly every install. The Feature Box admin screen is the demonstrated casualty: its duplicate-key branch never ran. Four more failure paths now record a number as well as the text. (#5993, #6040)
  • e_file::isValidURL() connects to the address its own policy check passed. It asked the outbound policy about the URL, then handed the URL as typed to fopen(), so the stream wrapper resolved the name again and connected wherever that answer pointed. Every other outbound path in the class already pins. The one-second budget now travels in the request context, and the status line is parsed as a code rather than searched as a substring. (#6027)
  • A suite run on a fresh checkout no longer dies before its first test. Anything printed before e107 loads sends the response headers, after which its own ini_set() calls on the session settings cannot take effect. The harness now generates Codeception's actor classes in its own process, and the suite bootstrap turns off display_errors before e107 boots. Bringing an existing environment up with different flags either takes effect or stops and tells you to recreate it, and ci-unit checks whether the running PHP has xdebug loaded rather than trusting a label. (#5884, #5950, #5937)

Acknowledgments

Thanks to

  • @orionhridoy for reporting eighteen of the twenty-two advisories, each with a working proof of concept, the affected files named, and an honest account of what the attack does and does not require: the two BBCode attribute cross-site scripting holes, the contact form that handed posted values back to the page as markup, the passwordless sign-in as a social-linked account, the second way in that a password change does not revoke, the login forged from one read of the database, the automatic ban that never counted a wrong password, the loose comparisons in the login paths, the session identifier that signing in left unchanged, the password change that needed no password, the database operations a page ran for an administrator who merely looked at it, the star rating one member could vote on over and over, and the forged Host header reflected into the site's addresses; and, in a second batch on September 5, the File Inspector link that ran script in an administrator's session, the private messages a page could delete, the member typeahead that answered anyone who asked, the FAQ entries that needed no account, and the comments accepted where they had been switched off; to
  • @3ng1 for reporting the language file editor code injection, with a working proof of concept, a correct root cause, and an explicit note on what the issue was not; to
  • @archnexus707 and, independently and six days later, @orionhridoy, for the member who could write any column on their own user row, including the two that make an account an administrator; both identified the broken guard on the confirmation stage exactly; to
  • @Jimmi08, whose reports run through this whole release: the unfetchable thumbnails and the blank "Sync with Github" page (#5893); the front end taken down by a deleted preference (#5928), which arrived with the fix worked out; the News Grid Featured count (#5955), the Menu Manager killed by {FEATUREBOX} (#5956), the Feature Box menu that drew nothing (#5957), the PDO driver reporting a SQLSTATE (#5993), the theme manager reading another theme's language file (#5996), the member list reporting no members (#6002), the Login menu's missing plugin statistics (#6044) and its statistics rendering outside the menu (#6048), the theme options that reported "saved" either way (#6018), and the Users Online page empty since 2019 (#6108) with its hand-built profile links (#6107). Her chatbox fork also identified the emote panel's dead first click (#5613) and the form actions that break search-engine-friendly URLs (#5614, #5616); to
  • @Alex-e107nl for scheduled tasks refusing every call after v2.3.11 (#5919), the error on saving the URL configuration page (#5921), the update that could not complete (#5904), the Credits page restyling the whole admin area (#5981), the open_basedir warnings filling Schedule Tasks > Setup (#5991), the silenced cache diagnostics reaching the PHP Errors panel (#5992), the contact form drawing a second CAPTCHA over a plugin's own (#6014), the ban durations and failed logins that could not be saved (#6051), the missing username placeholder (#6096), and the news page killed by a junk ?page= value (#6110); to
  • @BillyBoy0823 for the site link that lost part of its address after a sign-in setting changed (#5783), the user classes that did not survive an inline edit (#5779), and the two forum reply buttons that carried the same label (#5647); to
  • @sindizzy for the navigation menu that painted an empty box rather than saying it had no links to show (#6112); to
  • @tgtje for the undefined keys on the language pack verifier (#6109); to
  • @darkdi for the pull request that fixed the SMF importer's duplicated extension test, and for adding WebP to it (#6134); to
  • @rica-carv for the screenshot, posted in somebody else's issue, that turned out to be a second and unrelated fault: every unknown address on the site ended in a fatal error rather than the error page, tracked as #6024 (#6002); and to
  • @Kanonimpresor for confirming the broken avatars on the released v2.3.11 (#5893).

Full changelog: https://github.com/e107inc/e107/compare/v2.3.11...v2.3.12


Read more...

Posted September 5, 2026 | 9:37 am

View all e107 News...

Videos 0.18.0: Bring New Energy to Your Geeklog Audience with Video

Videos 0.18.0 is now available for Geeklog.

This release goes far beyond adding YouTube videos to a website. It turns video into a real content layer that can help a Geeklog site become more active, more engaging and easier to explore.

For a site built around a specific topic, this opens an interesting opportunity: use relevant videos to reconnect visitors with your existing content, highlight useful creators, surface remarkable resources and encourage people to stay longer on the site.

The new version is available from the Geeklog Plugins repository:

https://github.com/Geeklog-Plugins/videos

Video as Part of Your Editorial Strategy

Many websites already have years of articles, forum discussions, documentation or static pages.

The challenge is often no longer creating more content. It is finding new ways to make an existing audience want to explore the site again.

Video can help.

A gardening site can surface tutorials about composting or seed saving. A technical community can recommend demonstrations and conference talks. A climbing website can highlight training, safety and equipment videos. A local history site can build a catalogue around archives, documentaries and interviews.

Videos 0.18.0 is designed for exactly this kind of use.

Instead of treating YouTube as an external destination, the plugin builds a local video experience inside Geeklog.

Videos are discovered from YouTube, but visitors browse them through your site, your navigation, your editorial selections and your local recommendations.

This makes video another gateway into the community rather than a reason to leave it.

Build a Living Video Catalogue

Videos can maintain a public catalogue related to the theme of the site.

The plugin combines automated discovery with editorial control. Administrators can seed the discovery system with relevant searches and then let Videos maintain a bounded reservoir of potential content.

The public catalogue can take into account several signals, including search relevance, publication recency, local ratings, qualified views, viewing activity, priority channels and editorial selections.

This allows the catalogue to evolve over time instead of becoming a static list of embedded videos.

At the same time, the administrator remains in control.

A particularly useful video can be added permanently. An important video can be pinned. Unwanted videos can be removed or excluded from future automatic selection.

The goal is not automation for its own sake. The goal is to combine discovery with human editorial judgement.

Turn Video Discovery into Audience Discovery

One of the most interesting possibilities in Videos 0.18.0 is the ability to identify and promote relevant channels.

The plugin can build local rankings of remarkable videos and derive a ranking of channels from that content. Eligible channels can also receive their own local page inside the Geeklog site.

This can create a useful editorial loop.

A visitor arrives for one video, discovers another video on the same subject, explores the channel behind it, then continues through related videos and rankings without leaving the site immediately.

For niche websites, that can be particularly valuable.

A strong thematic site often does not need millions of visitors. It needs people who recognize that the site regularly surfaces useful material in their area of interest.

Videos can help create that feeling of ongoing discovery.

Recommendations Can Keep Visitors Exploring

A video page should not necessarily be the end of a visit.

Videos 0.18.0 includes local recommendation logic designed to offer sensible next videos while respecting moderation, viewing history, unavailable content and channel diversity.

Importantly, these recommendations can work from locally cached and ranked data. The plugin does not need to call the YouTube API every time a visitor loads a page.

That makes recommendations useful not only for engagement, but also for building stronger internal navigation.

A visitor may arrive from a search engine on one video page and then move through several related resources.

That is exactly the kind of browsing behaviour that can help breathe life back into a mature website.

Use Your Community's Own Signals

Videos does not have to reproduce YouTube's popularity rankings.

Geeklog can build its own signals.

The plugin supports local ratings, qualified local views, playback completion data and viewing history. These signals can contribute to rankings and recommendations.

This matters because the most popular video on YouTube is not necessarily the most useful video for your community.

A small specialist tutorial may be much more valuable to the visitors of a technical or enthusiast site than a video with millions of generic views.

Over time, local engagement gives the site a way to develop its own editorial intelligence.

Highlight the Best Videos Permanently

Automated discovery is useful for keeping a catalogue fresh, but some resources deserve a stable place.

Videos 0.18.0 introduces a stronger permanent catalogue model.

Administrators can manually add videos, keep them permanently available, pin especially important selections, remove them later, or prevent unwanted videos from being automatically reintroduced.

This makes it possible to gradually create a curated reference library.

For example, a site could maintain:

  • essential beginner videos;
  • important technical demonstrations;
  • interviews with recognized experts;
  • reference documentaries;
  • community favourites;
  • videos connected to important evergreen articles.

The automated catalogue can continue changing around this stable editorial foundation.

Create More Entry Points from Search Engines

The new version also places strong emphasis on SEO.

Public video pages can include canonical URLs, page-specific descriptions, Open Graph metadata, Twitter Card metadata and VideoObject structured data. The plugin also creates local navigation between videos, rankings, channels and catalogue pages.

This matters because every useful local video page can potentially become another entry point into the site.

A thematic Geeklog site may already rank well for articles written years ago. Video pages provide another way to cover the same subject from a different angle.

They can also strengthen internal links around a topic.

Instead of maintaining isolated articles and isolated embedded videos, the site can gradually develop small thematic ecosystems.

Integrate Videos with the Rest of Geeklog

Videos 0.18.0 also takes an important step toward broader Geeklog interoperability.

The plugin can expose videos, catalogues, rankings and channels through generic Geeklog content identities and canonical URL resolution. It can also generate lifecycle events when meaningful editorial changes occur.

This means other plugins do not need to understand how Videos stores its data internally.

Compatible plugins can react to a video being added, a ranking changing or a channel becoming important.

For example, IndexNow can be informed that an affected public URL has changed. Other content or notification plugins can eventually use the same signals.

This is an important direction for Geeklog: plugins becoming less isolated and more capable of cooperating around content.

Better Tools for Administrators

A dynamic catalogue only works if administrators can understand and control it.

Videos 0.18.0 reorganizes administration into four clearer areas:

Overview provides the general state of the plugin.

Actions contains editorial operations, discovery, maintenance and indexing tools.

Statistics provides information about the discovery reservoir, rankings, cache, YouTube API activity and SEO.

Moderation centralizes decisions about videos and channels.

The release also improves YouTube API diagnostics, quota visibility and failure messages.

This is particularly useful because a video catalogue should be able to run for long periods without requiring administrators to guess what the API is doing.

A Dynamic Block for the Rest of the Site

Videos can also contribute content outside the main catalogue.

Its optional Geeklog block can display recommended videos, top-rated videos, most-watched videos, recently active videos, random videos or notable channels.

That creates an easy way to make video discovery visible throughout an existing Geeklog site.

An article reader might notice a related video in a block. A forum visitor might discover a highly rated tutorial. A returning user might see a new selection from a priority channel.

These small points of discovery can help reconnect different parts of a site that have accumulated over many years.

A Way to Make an Established Site Feel Active Again

This may ultimately be the most interesting role for the Videos plugin.

Many long-running community websites do not lack content.

They lack movement.

Their archives are valuable, but visitors may not immediately see what is new, interesting or worth rediscovering.

A thematic video catalogue can provide that movement.

New videos appear. Older reference videos remain available. Visitors rate and watch them. Rankings evolve. Channels emerge. Recommendations connect one resource to another.

The surrounding Geeklog site suddenly has another living content stream.

And because the catalogue remains under local editorial control, the site keeps its own identity instead of becoming just another window into YouTube.

Videos 0.18.0 Availability

Videos 0.18.0 supports:

  • Geeklog 2.1.1 through 2.2.2;
  • PHP 5.6 through PHP 8.1;
  • YouTube Data API v3.

The source code and current release are available here:

https://github.com/Geeklog-Plugins/videos

If your Geeklog site is built around a clear subject and you are looking for a new way to engage visitors, Videos 0.18.0 is worth experimenting with.

The idea is simple: do not add video merely because video is popular.

Use video to strengthen the subject, personality and community that already make your site worth visiting.

Read more...

Posted August 29, 2026 | 9:09 am

View all Geeklog News...

View all Joomla News...

View all Nucleus News...

phpBB 3.3.15 Release - Please update

Greetings everyone,

We are pleased to announce the release of phpBB 3.3.15 “In Memory of Mark D. Hamill”. This version is a maintenance and security release of the 3.3.x branch which fixes one security issue, introduces a number of improvements aimed at enhancing the user experience and overall stability of the software and resolves some issues noticed in previous releases.

Since the introduction of phpBB 3.1, phpBB has been using JavaScript and jQuery to improve the responsiveness of prosilver. We did receive a report about a potentially dangerous code in this section. After an internal audit of this and related code, we noticed that some of the handling of data added by an admin is potentially insecure and could lead to cross site scripting.

The improvements include better handling of HTTPS connections in the version check since switching to Guzzle in the previous release as well as the introduction of proper support for TLS v1.3 with SMTP servers.

Notable bug fixes in this release include resolving an issue that resulted in PHP fatal errors when converting from phpBB 2 with Attachment MOD and issues with the pagination resulting in incorrect ordering when searching for users posts. Furthermore, an issue with duplicate users being displayed on the memberlist while sorting and a potential overflow of the topic views count have been addressed.

The full list of changes is available in the changelog file within the docs folder contained in the release package. You can find the key highlights of this release below and a list of all issues fixed on our tracker at https://tracker.phpbb.com/issues/?filter=16790

The packages can be downloaded from our downloads page.

The development team thanks everyone who contributed code to this release: rxu, Kailey M Snay, Alexey Dolzhenko, Neo-CTC, NeoDev, battye, cabot, phpBB TR

If you have any questions or comments, we'll be happy to address them in the discussion topic.

- The phpBB Team

Read more...

Posted April 2, 2025 | 6:58 am

View all phpBB News...

View all Plone News...

View all PHPNUKE News...

Re: MyBB 1.8 Convertor

Runs without errors.  Nothing changed in SMF install.

You cannot view this attachment.

Read more...

Posted September 7, 2026 | 5:54 pm

View all SMF News...

Students Built 108 Websites in Two Weeks in Bangladesh

In July, students at two campuses in Kishoreganj, Bangladesh, built 108 websites. In eastern Uganda, a workshop that arrived to find no electricity at the school ran anyway, for more than 100 learners, because a former student had asked for it. In Costa Rica, three university students taught a three-session WordPress class to 40 high […]

Read more...

Posted September 7, 2026 | 4:19 pm

View all WordPress News...

View all XOOPS News...

About | Contact | FAQ | Privacy Policy | Terms of Use

© 2006-2026 überbytes LLC