TYPO3 v15 dev-main snapshot ()

This commit is contained in:
2026-08-10 22:31:09 +02:00
commit af8cc155b5
6818 changed files with 642608 additions and 0 deletions
@@ -0,0 +1,56 @@
.. include:: /Includes.rst.txt
.. _deprecation-102099:
=========================================================
Deprecation: #102099 - Deprecate CKEditor 5 bundle module
=========================================================
See :issue:`102099`
Description
===========
With the CKEditor 5 integration in TYPO3 v12 a custom CKEditor 5 build in form of
a bundle has been introduced. Missing plugins had to be merged into that bundle
again and again which lead to an increased bundle size. Also plugin authors had
to reference the bundle module in order to fetch plugin exports from CKEditor.
With CKEditor 5 suggestion to use named exports from the CKEditor 5 package entry
point modules, it became feasible to create smaller bundles. One bundle per
scoped subpackage. For that reason :js:`@typo3/ckeditor5-bundle.js` is now
deprecated.
Impact
======
TYPO3 can ship all available CKEditor 5 modules and only actually requested modules
are loaded. Developers can write plugins as suggested by upstream documentation.
Affected Installations
======================
Installations having custom extensions activated, that provide custom CKEditor 5
plugins. Extensions that use:js:`@typo3/ckeditor5-bundle.js` will still work
as before (as the bundle module re-exports the exports of the split bundles)
but will trigger a deprecation log message to the browser console.
Migration
=========
Extension authors should import from scoped :js:`@ckeditor/ckeditor5-*` packages
directly.
.. code-block:: javascript
// Before
import {Core, UI} from '@typo3/ckeditor5-bundle.js';
// After
import * as Core from '@ckeditor/ckeditor5-core';
import * as UI from '@ckeditor/ckeditor5-ui';
.. index:: PHP-API, NotScanned, ext:core
@@ -0,0 +1,151 @@
.. include:: /Includes.rst.txt
.. _feature-106743-1747931468:
=============================================
Feature: #106743 - Introduce Sudo-Mode Events
=============================================
See :issue:`106743`
Description
===========
The fix for the security advisory `TYPO3-CORE-SA-2025-013 <https://typo3.org/security/advisory/typo3-core-sa-2025-013>`_
requires step-up authentication when attempting to manipulate backend user accounts.
However, this behavior may pose challenges when integrating remote single sign-on (SSO)
providers, as these typically do not support a dedicated step-up authentication process.
To address this, new PSR-14 events have been introduced:
* :php:`TYPO3\CMS\Backend\Security\SudoMode\Event\SudoModeRequiredEvent` is triggered before
showing the sudo-mode verification dialog
* :php:`TYPO3\CMS\Backend\Security\SudoMode\Event\SudoModeVerifyEvent` is triggered before
actually verifying the submitted password
This event allows developers to conditionally bypass and adjust the step-up authentication
process based on custom logic, such as identifying users authenticated through an SSO system.
Example
-------
The following example demonstrates how to use an event listener to skip the step-up authentication
for persisted `be_users` records with an active `is_sso` flag:
.. code-block:: yaml
:caption: EXT:my_extension/Configuration/Services.yaml
services:
Vendor\MyExtension\EventListener\SkipSudoModeDialog:
tags:
- name: event.listener
identifier: 'ext-myextension/skip-sudo-mode-dialog'
Vendor\MyExtension\EventListener\StaticPasswordVerification:
tags:
- name: event.listener
identifier: 'ext-myextension/static-password-verification'
.. code-block:: php
:caption: EXT:my_extension/Classes/EventListener/SkipSudoModeDialog.php
<?php
declare(strict_types=1);
namespace Vendor\MyExtension\EventListener;
use TYPO3\CMS\Backend\Hooks\DataHandlerAuthenticationContext;
use TYPO3\CMS\Backend\Security\SudoMode\Access\AccessSubjectInterface;
use TYPO3\CMS\Backend\Security\SudoMode\Access\TableAccessSubject;
use TYPO3\CMS\Backend\Security\SudoMode\Event\SudoModeRequiredEvent;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
final class SkipSudoModeDialog
{
public function __invoke(SudoModeRequiredEvent $event): void
{
// Ensure the event context matches DataHandler operations
if ($event->getClaim()->origin !== DataHandlerAuthenticationContext::class) {
return;
}
// Filter for TableAccessSubject types only
$tableAccessSubjects = array_filter(
$event->getClaim()->subjects,
static fn (AccessSubjectInterface $subject): bool => $subject instanceof TableAccessSubject
);
// Abort if there are unhandled subject types
if ($event->getClaim()->subjects !== $tableAccessSubjects) {
return;
}
/** @var list<TableAccessSubject> $tableAccessSubjects */
foreach ($tableAccessSubjects as $subject) {
// Expecting format: tableName.fieldName.id
if (substr_count($subject->getSubject(), '.') !== 2) {
return;
}
[$tableName, $fieldName, $id] = explode('.', $subject->getSubject());
// Only handle be_users table
if ($tableName !== 'be_users') {
return;
}
// Skip if ID is not a valid integer (e.g., 'NEW' records)
if (!MathUtility::canBeInterpretedAsInteger($id)) {
continue;
}
$record = BackendUtility::getRecord($tableName, $id);
// Abort if any record does not use SSO
if (empty($record['is_sso'])) {
return;
}
}
// All conditions met — disable verification
$event->setVerificationRequired(false);
}
}
.. code-block:: php
:caption: EXT:my_extension/Classes/EventListener/StaticPasswordVerification.php
<?php
declare(strict_types=1);
namespace Example\Demo\EventListener;
use TYPO3\CMS\Backend\Security\SudoMode\Event\SudoModeVerifyEvent;
final class StaticPasswordVerification
{
public function __invoke(SudoModeVerifyEvent $event): void
{
$calculatedHash = hash('sha256', $event->getPassword());
// static hash of `dontdothis` - just used as proof-of-concept
// side-note: in production, make use of strong salted password
$expectedHash = '3382f2e21a5471b52a85bc32ab59ab2c467f6e3cb112aef295323874f423994c';
if (hash_equals($expectedHash, $calculatedHash)) {
$event->setVerified(true);
}
}
}
Impact
======
This feature provides extension developers with a flexible mechanism to skip or adjust
step-up authentication during sensitive backend operations. It is especially useful in
environments utilizing SSO, where enforcing additional verification might not be feasible
or necessary. By hooking into the new :php:`SudoModeRequiredEvent` and :php:`SudoModeVerifyEvent`
custom logic and behavior can be applied on a case-by-case basis.
.. index:: Backend, ext:backend
@@ -0,0 +1,62 @@
.. include:: /Includes.rst.txt
.. _important-100847-1686218342:
====================================================
Important: #100847 - Added font plugin to CKEditor 5
====================================================
See :issue:`100847`
Description
===========
The font plugin has been added to the CKEditor 5.
In order to use the font plugin, the RTE configuration needs to be adapted:
.. code-block:: yaml
editor:
config:
toolbar:
items:
# add button to select font family
- fontFamily
# add button to select font size
- fontSize
# add button to select font color
- fontColor
# add button to select font background color
- fontBackgroundColor
fontColor:
colors:
- { label: 'Orange', color: '#ff8700' }
- { label: 'Blue', color: '#0080c9' }
- { label: 'Green', color: '#209d44' }
fontBackgroundColor:
colors:
- { label: 'Stage orange light', color: '#fab85c' }
fontFamily:
options:
- 'default'
- 'Arial, sans-serif'
fontSize:
options:
- 'default'
- 18
- 21
importModules:
- { 'module': '@ckeditor/ckeditor5-font', 'exports': ['Font'] }
More information can be found in the official documentation_.
.. _documentation: https://ckeditor.com/docs/ckeditor5/latest/features/font.html
.. index:: RTE, ext:rte_ckeditor
@@ -0,0 +1,43 @@
.. include:: /Includes.rst.txt
.. _important-100889-1690476871:
=======================================================================
Important: #100889 - Allow insecure site resolution by query parameters
=======================================================================
See :issue:`100889`
.. important::
This change was introduced as part of the
`TYPO3 v12.4.4 and v11.5.30 security releases <https://typo3.org/security/advisory/typo3-core-sa-2023-003>`__.
Description
===========
Resolving sites by the `id` and `L` HTTP query parameters is now denied by
default. However, it is still allowed to resolve a particular page by, for
example, "example.org" - as long as the page ID `123` is in the scope of the
site configured for the base URL "example.org".
The new feature flag
`security.frontend.allowInsecureSiteResolutionByQueryParameters` - which is
disabled per default - can be used to reactivate the previous behavior:
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.frontend.allowInsecureSiteResolutionByQueryParameters'] = true;
Impact
======
Resolving a page via query parameters is now restricted to the specific
site where the page is located.
Affected installations
======================
Installations which resolve pages from one domain via another domain.
.. index:: Frontend, NotScanned, ext:core
@@ -0,0 +1,37 @@
.. include:: /Includes.rst.txt
.. _important-100925-1686234441:
========================================================================
Important: #100925 - Use dedicated cache for database schema information
========================================================================
See :issue:`100925`
Description
===========
To implement native JSON database field and TCA `type=json`
support for TYPO3 v12 the need to cache the database schema
information raised due to performance reason.
Using the core cache for schema information comes with
various drawbacks:
#. There is no way to flush single core cache entries,
thus the complete core cache needs to be flushed when
changing the database schema.
#. The PHP Frontend provides no benefit, when the to be cached
information has to be serialized anyway.
Therefore, a new cache is introduced that can be flushed
individually after schema updates.
Additionally, some internal steps taken to mitigate some side
effects are reverted. They are no longer needed with the dedicated
cache.
Due to the nature of the chosen cache no database updates,
configuration changes or other steps are needed.
.. index:: Database, ext:core
@@ -0,0 +1,31 @@
.. include:: /Includes.rst.txt
.. _important-101128-1723726464:
===========================================================================
Important: #101128 - CKEditor's highlight plugin introduces `mark` HTML tag
===========================================================================
See :issue:`101128`
Description
===========
The introduction of the CKEditor plugin :js:`@ckeditor/ckeditor5-language`
allows an editor to use the :html:`mark` tag, as well as the :html:`s` tag.
It may become necessary to explicitly allow this tag in the
:typoscript:`lib.parseFunc_RTE` TypoScript setup to allow the tag to be
rendered properly in the frontend:
.. code-block:: typoscript
lib.parseFunc_RTE {
allowTags := addToList(mark,s)
}
Custom CSS styling for different markers classes needs to be
implemented in a sitepackage for example, as no frontend
CSS for this is emitted by default.
.. index:: Frontend, RTE, TSConfig, ext:core
@@ -0,0 +1,69 @@
.. include:: /Includes.rst.txt
.. _important-101567-1691227840:
========================================================================
Important: #101567 - Use Symfony attribute to autoconfigure cli commands
========================================================================
See :issue:`101567`
Description
===========
The Symfony PHP attribute :php:`\Symfony\Component\Console\Attribute\AsCommand`
is now accepted to register console commands.
This way CLI commands can be registered by setting the attribute on the command
class. Only the parameters `command`, `description`, `aliases` and `hidden` are
still viable. In order to overwrite the schedulable parameter use the old
:file:`Services.yaml` way to register console commands. By default `schedulable`
is true.
Before:
.. code-block:: yaml
:caption: EXT:my_extension/Configuration/Services.yaml
MyVendor\MyExtension\Command\MyCommand:
tags:
- name: 'console.command'
command: 'myprefix:dofoo'
description: 'My description'
schedulable: true
- name: 'console.command'
command: 'myprefix:dofoo-alias'
alias: true
After:
The registration can be removed from the :file:`Services.yaml` file and the
attribute is assigned to the command class instead:
.. code-block:: php
:caption: EXT:my_extension/Classes/Command/MyCommand.php
<?php
namespace MyVendor\MyExtension\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Attribute\AsCommand;
#[AsCommand(
name: 'myprefix:dofoo',
description: 'My description',
aliases: ['myprefix:dofoo-alias']
)]
class MyCommand extends Command
{
}
Impact
======
The registration of cli commands is simplified that way.
When using this attribute there is no need to register the command in the
:file:`Services.yaml` file. Existing configurations work as before.
.. index:: Backend, CLI, PHP-API, ext:core
@@ -0,0 +1,29 @@
.. include:: /Includes.rst.txt
.. _important-101580-1723653576:
===========================================================================
Important: #101580 - Introduce Content-Security-Policy-Report-Only handling
===========================================================================
See :issue:`101580`
Description
===========
The feature flag `security.frontend.reportContentSecurityPolicy`
(:php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.frontend.reportContentSecurityPolicy']`)
can be used to apply the `Content-Security-Policy-Report-Only` HTTP header for
frontend responses.
When both feature flags are activated, both headers are sent.
You can deactivate one disposition in the site-specific configuration.
This allows to test and assess the potential impact on introducing
Content-Security-Policy in the frontend - without actually blocking
any functionality.
This behavior can be controlled on a site-specific scope as well, see
:ref:`Important: #104549 - Introduce site-specific Content-Security-Policy-Disposition <important-104549-1723461851>`.
.. index:: Frontend, LocalConfiguration, ext:frontend
@@ -0,0 +1,27 @@
.. include:: /Includes.rst.txt
.. _important-101776-1694342579:
===================================================================================================
Important: #101776 - Email validation in GeneralUtility::validEmail() now rejects spaces before "@"
===================================================================================================
See :issue:`101776`
Description
===========
The :php:`GeneralUtility::validEmail()` method uses the package :composer:`egulias/email-validator`
for validating emails.
This library treats an email address like :samp:`email @example.com` with a space before the `@`
character as valid, but issues a warning, which has previously not been caught by TYPO3. Warnings
like these are defined as "deviations from the RFC that in a broader interpretation are accepted."
In the context of TYPO3, such non-RFC email address shall be rejected.
Thus, this specific warning (:php:`CFWSNearAt`) will now be caught, and the warning is turned into an
invalidation of the given email address.
This will have the effect, that if integrators previously accepted email addresses formatted like
these, validation will now fail (as the RFC implies).
.. index:: Backend, ext:core
@@ -0,0 +1,50 @@
.. include:: /Includes.rst.txt
.. _important-102314-1699259952:
=========================================================
Important: #102314 - Add title argument to IconViewhelper
=========================================================
See :issue:`102314`
Description
===========
The `IconViewhelper` in EXT:core has been extended with a new argument `title`.
The new argument allows to set a corresponding title, which will be rendered
as `title` attribute in the icon HTML markup. The `title` attribute will only
be rendered, if explicitly passed. You can also pass an empty string.
This `title` attribute will improve accessibility, since screenreaders can
choose not to ignore aria-hidden elements (e.g. the icons above the page tree),
which is a mode people with low visibility might choose. If a `title` attribute
is missing, a purely technical output will be given, which is very hard to
make sense of.
Example
=======
.. code-block:: html
<core:icon title="Open actions menu" identifier="actions-menu" />
This will be rendered as:
.. code-block:: html
<span
title="Open actions menu"
class="t3js-icon icon icon-size-small icon-state-default icon-actions-menu"
data-identifier="actions-menu" aria-hidden="true"
>
<span class="icon-markup">
<img
src="/typo3/sysext/core/Resources/Public/Icons/T3Icons/actions/actions-menu.svg"
width="16"
height="16"
>
</span>
</span>
.. index:: Backend, NotScanned, ext:core
@@ -0,0 +1,56 @@
.. include:: /Includes.rst.txt
.. _important-102507-1702317316:
=================================================================================================
Important: #102507 - Default CKEditor 5 allowed classes and data attributes configurated reverted
=================================================================================================
See :issue:`102507`
Description
===========
With TYPO3 v12.4.7 (see :issue:`99738`) an option to allow all classes in
CKEditor 5 has been enabled in the TYPO3 default configuration which implicitly
caused all custom html elements to be allowed. This rule has now been dropped
from the default configuration:
.. code-block:: yaml
editor:
config:
htmlSupport:
allow:
- { classes: true, attributes: { pattern: 'data-.+' } }
The configuration matched to any HTML element available in the CKEditor 5 General
HTML Support (GHS) schema definition.
This became an issue, since CKEditor 5 relies on the set of allowed elements and
classes when processing content that is pasted from Microsoft Office.
Installations that relied on the fact that v12.4.7 allowed all CSS classes in
CKEditor 5 should encode the set of available style definitions via
:yaml:`editor.config.style.definitions` which will make them accessible to editors
via the style dropdown toolbar element:
.. code-block:: yaml
editor:
config:
style:
definitions:
- { name: "Descriptive Label", element: "p", classes: ['my-class'] }
Custom data attributes can be allowed via General HTML Support:
.. code-block:: yaml
editor:
config:
htmlSupport:
allow:
- { name: 'div', attributes: ['data-foobar'] }
.. index:: RTE, YAML, ext:rte_ckeditor
@@ -0,0 +1,80 @@
.. include:: /Includes.rst.txt
.. _important-102904-1706702424:
============================================================
Important: #102904 - Use TCA group field as foreign selector
============================================================
See :issue:`102904`
Description
===========
When using TCA type :php:`inline`, developers have the possibility to use the
"foreign selector" feature by defining the :php:`foreign_selector` option,
pointing to a field on the foreign (child) table. This way, editors can
use the corresponding selector field to choose existing child records,
to create a new inline relation. This can be further extended, using the
:php:`useCombination` appearance option, which allows to modify the child record
via the parent record globally.
The field referenced in :php:`foreign_selector` is usually a field with TCA type
:php:`select`, using the `foreign_table` option itself to provide the corresponding
items to choose.
It's nevertheless also possible to use a TCA type :php:`group` field as
:php:`foreign_selector`. In this case, the child records have to be selected
from the table, defined via the :php:`allowed` option. For this use case,
**only one table** can be defined. This means, the first table name in
:php:`allowed` is taken, no matter if there are multiple table names defined.
.. note::
This unfortunately does not work out of the box for Extbase. Therefore, the
corresponding table has to be defined additionally via the :php:`foreign_table`
option. This option is only used as a
`workaround <https://docs.typo3.org/m/typo3/reference-tca/main/en-us/ColumnsConfig/Type/Group/Properties/ForeignTable.html>`__
by Extbase and is not sufficient for the TYPO3 Form editor, which will always
just consider the value from the :php:`allowed` option.
Example using an intermediate table and the :php:`useCombination` feature:
.. code-block:: php
// Inline field in parent table "tx_extension_inline_usecombination"
'inline' => [
'label' => 'inline',
'config' => [
'type' => 'inline',
'foreign_table' => 'tx_extension_inline_usecombination_mm', // Referencing the intermediate table
'foreign_field' => 'group_parent',
'foreign_selector' => 'group_child',
'foreign_unique' => 'group_child',
'appearance' => [
'useCombination' => true,
],
],
],
// Reference fields in intermediate table "tx_extension_inline_usecombination_mm"
'group_parent' => [
'label' => 'group parent',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'foreign_table' => 'tx_extension_inline_usecombination', // Referencing the parent table
],
],
'group_child' => [
'label' => 'group child',
'config' => [
'type' => 'group',
'allowed' => 'tx_extension_inline_usecombination_child', // Referencing the child table
'foreign_table' => 'tx_extension_inline_usecombination_child', // ONLY USED FOR extbase!
],
],
// Child table "tx_extension_inline_usecombination_child" does not have any relation fields
.. index:: Backend, PHP-API, TCA, ext:backend
@@ -0,0 +1,49 @@
.. include:: /Includes.rst.txt
.. _important-103392-1710345611:
=========================================================
Important: #103392 - Form framework select markup changed
=========================================================
See :issue:`103392`
Description
===========
With :issue:`103117`, the `elementClassAttribute` of the "SingleSelect",
"CountrySelect" and "MultiSelect" fields got changed from `form-control` to
`form-select` in EXT:form, as defined by `Bootstrap`_, if the Bootstrap 5 markup
(:yaml:`templateVariant: version2`) is used.
If needed, the old markup can be restored by overriding the configuration as
follows:
.. code-block:: yaml
:emphasize-lines: 9,15,21
prototypes:
standard:
formElementsDefinition:
CountrySelect:
variants:
-
identifier: template-variant
properties:
elementClassAttribute: form-control
MultiSelect:
variants:
-
identifier: template-variant
properties:
elementClassAttribute: form-control
SingleSelect:
variants:
-
identifier: template-variant
properties:
elementClassAttribute: form-control
.. _Bootstrap: https://getbootstrap.com/docs/5.3/forms/select/
.. index:: Frontend, ext:form
@@ -0,0 +1,25 @@
.. include:: /Includes.rst.txt
.. _important-103496-1711623416:
=======================================================
Important: #103496 - ISO format used for date rendering
=======================================================
See :issue:`103496`
Description
===========
The default format for date rendering configured in :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy']` has changed.
The former arbitrary :php:`'d-m-y'` format was replaced with the standard ISO 8601 :php:`'Y-m-d'` format.
Examples of dates where the :php:`'d-m-y'` format led to unclear dates:
* A 2-digit year could also be a day in a month: `21-04-23` could be understood as `2021-04-23` instead of `2023-04-21`.
* The century of years could not be distinguished: `21-04-71` could be `2071-04-21` or `1971-04-21`
This affects date display in various locations so code relying on the previous format (e.g. acceptance tests) must be updated accordingly.
.. index:: Backend, CLI, Frontend, TCA, ext:core
@@ -0,0 +1,135 @@
.. include:: /Includes.rst.txt
.. _important-104549-1723461851:
================================================================================
Important: #104549 - Introduce site-specific Content-Security-Policy-Disposition
================================================================================
See :issue:`104549`
Description
===========
The feature flags :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.frontend.enforceContentSecurityPolicy']`
and :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.frontend.reportContentSecurityPolicy']` apply
Content-Security-Policy headers to any frontend site. The dedicated :file:`sites/<my-site>/csp.yaml` can now be
used as alternative to declare the desired disposition of `Content-Security-Policy` and
`Content-Security-Policy-Report-Only` individually.
It now is also possible, to apply both `Content-Security-Policy` and `Content-Security-Policy-Report-Only`
HTTP headers at the same time with different directives for a particular site. Besides that it is possible
to disable the disposition completely for a site.
The following new configuration schemes were introduced for :file:`sites/<my-site>/csp.yaml`:
* `active (false)` for disabling CSP for a particular site, which overrules any other setting for `enforce` or `report`
* `enforce (bool|disposition-array)` for compiling the `Content-Security-Policy` HTTP header
* `report (bool|disposition-array)` for compiling the `Content-Security-Policy-Report-Only` HTTP header
The `disposition-array` for `enforce` and `report` allows these properties:
* `inheritDefault (bool)` inherits default site-unspecific frontend policy mutations (`true` per default)
* `includeResolutions (bool)` includes dynamic resolutions, as persisted in the database via backend module (`true` per default)
* `mutations (mutation-item-array)` defines additional directive mutations to be applied to the specific site
* `packages (package-item-array)` defines packages/extensions whose static CSP mutations shall be dropped or included
Example: Disable Content-Security-Policy
----------------------------------------
The following example would completely disable CSP for a particular site.
.. code-block:: yaml
:caption: config/sites/<my-site>/csp.yaml
# `active` is enabled per default if omitted
active: false
Example: Use `report` disposition
---------------------------------
The following example would dispose only `Content-Security-Policy-Report-Only`
for a particular site (since the `enforce` property is not given).
.. code-block:: yaml
:caption: config/sites/<my-site>/csp.yaml
report:
# `inheritDefault` is enabled per default if omitted
inheritDefault: true
mutations:
- mode: extend
directive: img-src
sources:
- https://*.typo3.org
The following example is equivalent to the previous, but shows that the
legacy configuration (having `inheritDefault` and `mutations` on the top-level)
is still supported.
The effective HTTP headers would then be resolved from the active feature flags
`security.frontend.enforceContentSecurityPolicy` and
`security.frontend.reportContentSecurityPolicy` - in case both flags are active,
both HTTP headers `Content-Security-Policy` and `Content-Security-Policy-Read-Only`
would be used.
.. code-block:: yaml
:caption: config/sites/<my-site>/csp.yaml
# `inheritDefault` is enabled per default if omitted
inheritDefault: true
mutations:
- mode: extend
directive: img-src
sources:
- https://*.typo3.org
Example: Use `enforce` and `report` dispositions at the same time
-----------------------------------------------------------------
The following example would dispose `Content-Security-Policy` (`enforce`)
and `Content-Security-Policy-Report-Only` (`report`) for a particular site.
This allows to test new CSP directives in the frontend - the example drops
the static CSP directives of the package `my-vendor/my-package` in the
enforced disposition and only applies it to the reporting disposition.
.. code-block:: yaml
:caption: config/sites/<my-site>/csp.yaml
enforce:
# `inheritDefault` is enabled per default if omitted
inheritDefault: true
# `includeResolutions` is enabled per default if omitted
includeResolutions: true
mutations:
- mode: extend
directive: img-src
sources:
- https://*.typo3.org
packages:
# all (`*`) packages shall be included (`true`)
'*': true
# the package `my-vendor/my-package` shall be dropped (`false`)
my-vendor/my-package: false
report:
# `inheritDefault` is enabled per default if omitted
inheritDefault: true
# `includeResolutions` is enabled per default if omitted
includeResolutions: true
mutations:
- mode: extend
directive: img-src
sources:
- https://*.my-vendor.example.org/
# the `packages` section can be omitted in this case, since all packages
# listed there shall be included - which is the default behavior in case
# `packages` would not be configured
packages:
# all (`*`) packages shall be included (`true`)
'*': true
# the package `my-vendor/my-package` shall be included (`true`)
my-vendor/my-package: true
.. index:: Frontend, YAML, ext:frontend
@@ -0,0 +1,53 @@
.. include:: /Includes.rst.txt
.. _important-104693-1725960199:
==============================================================================
Important: #104693 - Setting allowLanguageSynchronization via columnsOverrides
==============================================================================
See :issue:`104693`
Description
===========
Setting the TCA option :php:`allowLanguageSynchronization` for a specific
column in a record type via :php:`columnsOverrides` is currently not supported
by TYPO3 and therefore might lead to exceptions in the corresponding field wizard
(:php:`LocalizationStateSelector`). To mitigate this, the option is now
automatically removed from the TCA configuration via a TCA migration. A
corresponding deprecation log entry is added to inform integrators about
the necessary code adjustments.
Migration
=========
Remove the :php:`allowLanguageSynchronization` option from :php:`columnsOverrides`
for now.
.. code-block:: php
// Before
'types' => [
'text' => [
'showitem' => 'header',
'columnsOverrides' => [
'header' => [
'config' => [
'behaviour' => [
'allowLanguageSynchronization' => true
],
],
],
],
],
],
// After
'types' => [
'text' => [
'showitem' => 'header',
],
],
.. index:: Backend, TCA, ext:backend
@@ -0,0 +1,106 @@
.. include:: /Includes.rst.txt
.. _important-104827-1725611875:
======================================================================
Important: #104827 - Allow to use Regular Expressions in CKEditor YAML
======================================================================
See :issue:`104827`
Description
===========
The CKEditor plugin can now be configured with YAML syntax utilizing
Regular Expression objects for certain keys. By defining a Regular Expression,
the CKEditor replacement/transformation functionality feature is now fully
usable.
The CKEditor 5 configuration API allows to specify
Regular Expression JavaScript objects, for example in
:javascript:`editor.config.typing.transformations.extra.from` or
:javascript:`editor.config.htmlSupport.allow.name`:
.. code-block:: javascript
:caption: Example CKEditor JavaScript configuration excerpt
// part of `editor.config`
{
typing: {
transformations: {
extra: {
from: /(tsconf|t3ts)$/,
to: 'TYPO3 TypoScript TSConfig'
}
}
}
htmlSupport: {
allow: {
name: /^(div|section|article)$/
}
}
}
When TYPO3 passes YAML configuration of the CKEditor forward
to JavaScript, it uses a html-entity encoded representation,
which does not allow to utilize Regular Expression objects,
and also the CKEditor API method `buildQuotesRegExp()` is not
usable in this scenario.
This was remedied already for the configuration key :yaml:`htmlSupport`
with its sub-keys, so that when a YAML key named :yaml:`pattern`
was found, TYPO3 automatically converted that to a proper JavaScript
Regular Expression:
.. code-block:: yaml
:caption: Example YAML RTE configuration excerpt
editor:
config:
htmlSupport:
allow:
- { name: { pattern: '^(div|section|article)$', flags: '' } }
.. important::
Please note that the `/` character from the beginning and end
of the regular expression must not be specified manually in YAML.
Also take care of the ending `$` character, which is vital to CKEditor's
proper parsing of a rule. The :yaml:`flags` key can contain Regular
Expression flags, and can also be omitted.
This is now also possible for the `editor.config.typing.transformations`
structure:
.. code-block:: yaml
:caption: Example YAML RTE configuration excerpt
editor:
config:
typing:
transformations:
extra:
- { from: { pattern: '(tsconf|t3ts)$', flags: '' }, to: 'TYPO3 TypoScript TSConfig' }
This conversion of Regular Expressions must be explicitly applied to
CKEditor configuration keys within the TYPO3 API, and cannot be used
generally for every key.
Thus, using a :yaml:`pattern` sub-key is currently applied only to the following
configuration structures (and recursively their sub-structures):
* :yaml:`editor.config.typing.transformations`
* :yaml:`editor.config.htmlSupport`
.. hint::
This means, that the `pattern` sub-key can be used for all of:
* :yaml:`editor.config.htmlSupport.[...].name`
* :yaml:`editor.config.htmlSupport.[...].styles`
* :yaml:`editor.config.htmlSupport.[...].classes`
* :yaml:`editor.config.htmlSupport.[...].attributes`
* :yaml:`editor.config.typing.transformations.extra[...].from`
.. index:: RTE, , ext:rte_ckeditor
@@ -0,0 +1,106 @@
.. include:: /Includes.rst.txt
.. _important-104839-1726124400:
================================================================================
Important: #104839 - RTE processing YAML configuration now respects `removeTags`
================================================================================
See :issue:`104839`
Description
===========
.. important::
Short version: With this bugfix, any save process
to the contents of an existing RTE element will now properly apply
the :yaml:`removeTags` default configuration (unless configured otherwise).
To prevent a breaking change, the tags :html:`center`, :html:`font`, :html:`strike` and
:html:`u` are now allowed to be saved by default (like it was with the bug in
effect). This is planned to be changed with TYPO3 v14 as a breaking change.
The unexpected tags :html:`link`, :html:`meta`, :html:`o:p`, :html:`sdfield`,
:html:`style`, :html:`title` will now be removed.
This behaviour can always be customized by setting :yaml:`removeTags` appropriately.
TYPO3 allows to configure which HTML tags are allowed to be persisted
to the database in case of Richtext-elements. This can be configured
either within the CKEditor YAML context, or via Page TSconfig:
.. code-block:: yaml
:caption: EXT:rte_ckeditor/Configuration/RTE/Processing.yaml
processing:
HTMLparser_db:
# previous default: center, font, link, meta, o:p, sdfield,
# style, title, strike, u
removeTags: [link, meta, o:p, sdfield, style, title]
.. code-block:: typoscript
:caption: EXT:my_extension/Configuration/TypoScript/page.tsconfig
RTE.default.proc {
HTMLparser_db {
removeTags = link, meta, o:p, sdfield, style, title
}
}
Due to a bug in interpreting the YAML configuration, the syntax using
an array was actually never in effect.
This means, any implementation relying on such a YAML configuration (without
providing Page TSconfig), would not have removed the listed tags.
Due to TYPO3's internal processing, from those tags listed above,
the previous default tags :html:`center`, :html:`font`, :html:`strike` and
:html:`u` were persisted to the database and also later evaluated in the frontend.
The other tags :html:`link`, :html:`meta`, :html:`o:p`, :html:`sdfield`,
:html:`style` and :html:`title` were displayed as HTML encoded entities
due to other sanitizing in the output (but still stored as HTML tags in the database).
These tags will no longer be stored by default now, and is considered a non-breaking
bugfix, because these tags should not occur within an RTE.
This wrong parsing has now been fixed, so that now both an `array` syntax as
well as `string` syntax is allowed in the YAML processing and will
be applied. Adapting the :yaml:`removeTags` setting allows to change
the now applied defaults to any tag configuration needed.
.. hint::
Custom YAML configuration that used a `string` representation of :yaml:`removeTags`
(instead of an `array`) was already properly evaluated.
This bugfix has not been backported to TYPO3 v11 installations, to prevent
a change of behaviour in a security-maintenance-only environment. If this fix
is needed, you can convert the CKEditor array syntax by removing the square
brackets in a :file:`Processing.yaml` override:
.. code-block:: yaml
removeTags: [center, font, link, meta, o:p, sdfield, strike, style, title, u]
to:
.. code-block:: yaml
removeTags: center, font, link, meta, o:p, sdfield, strike, style, title, u
Affected installations
======================
TYPO3 setups with RTE YAML configurations utilizing either a custom
:yaml:`removeTags` processing directive or the default, defined via `array`
notation instead of `string`.
Migration
=========
Adjust the RTE YAML configuration processing directive `removeTags`
to suit the expected tag removal, or accept the new defaults.
.. index:: RTE, TSConfig, Backend, NotScanned
@@ -0,0 +1,61 @@
.. include:: /Includes.rst.txt
.. _important-105856-1737555887:
==========================================================================
Important: #105856 - Allow site-specific Content-Security-Policy endpoints
==========================================================================
See :issue:`105856`
Description
===========
The way Content-Security-Policy reporting endpoints are configured has
been enhanced. Administrators can now disable the reporting endpoint
globally or configure it per site as needed.
The global scope-specific setting `contentSecurityPolicyReportingUrl` can
be set to zero ('0') to disable the CSP reporting endpoint:
* :php:`[TYPO3_CONF_VARS][FE][contentSecurityPolicyReportingUrl] = '0'`
* :php:`[TYPO3_CONF_VARS][BE][contentSecurityPolicyReportingUrl] = '0'`
Additionally, the behavior of the reporting endpoint can also be
configured per site via :file:`sites/<my-site>/csp.yaml`.
The new disposition-specific property `reportingUrl` can either be:
* `reportingUrl (true)` to enable the reporting endpoint
* `reportingUrl (false)` to disable the reporting endpoint
* `reportingUrl (string)` to use the given value as external reporting endpoint
If defined, the site-specific configuration takes precedence over
the global configuration.
In case the explicitly disabled endpoint still would be called, the
server-side process responds with a 403 HTTP error message.
Example: Disabling the reporting endpoint
-----------------------------------------
.. code-block:: yaml
:caption: config/sites/<my-site>/csp.yaml
enforce:
inheritDefault: true
mutations: {}
reportingUrl: false
Example: Using custom external reporting endpoint
-------------------------------------------------
.. code-block:: yaml
:caption: config/sites/<my-site>/csp.yaml
enforce:
inheritDefault: true
mutations: {}
reportingUrl: https://example.org/csp-report
.. index:: Backend, Frontend, YAML, ext:backend
@@ -0,0 +1,45 @@
.. include:: /Includes.rst.txt
.. _important-106229-1747304339:
======================================================================
Important: #106229 - Allow filtering request hosts in webhook messages
======================================================================
See :issue:`106229`
Description
===========
To protect against DNS rebinding, the list of allowed hostnames that webhook
handlers will connect to can be configured as a list in
:php:`$GLOBALS['TYPO3_CONF_VARS']['HTTP']['allowed_hosts']['webhooks']`.
To add a host to the allowlist, it can be appended to the mentioned array.
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['HTTP']['allowed_hosts']['webhooks'][] = 'example.com';
You can substitute parts of the domain with a wildcard character :php:`'*'`
(matches one or multiple characters, no regex syntax supported).
For example, :php:`'*.example.com'` is valid, and accepts all domains ending in
`.example.com`, also `foo.bar.example.com`:
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['HTTP']['allowed_hosts']['webhooks'][] = '*.example.com';
By default when the `webhooks` key in `allowed_hosts` is unset or null all
hosts are allowed.
An empty array will cause all webhooks requests to be blocked:
.. code-block:: php
// Block all webhook targets by specifying an empty array.
// You might better want to remove ext:webhooks if you want to do this.
$GLOBALS['TYPO3_CONF_VARS']['HTTP']['allowed_hosts']['webhooks'] = [];
.. index:: LocalConfiguration, ext:webhooks
@@ -0,0 +1,79 @@
.. include:: /Includes.rst.txt
.. _important-106240-1747316969:
===============================================================================================
Important: #106240 - Enforce File Extension and MIME-Type Consistency in File Abstraction Layer
===============================================================================================
See :issue:`106240`
Description
===========
The following methods of :php:`ResourceStorage` have been improved to enhance
consistency and security for both existing and uploaded files:
* :php:`addFile`
* :php:`renameFile`
* :php:`replaceFile`
* :php:`addUploadedFile`
Key enhancements
----------------
* Only explicitly allowed file extensions are accepted. These must be configured
under the following sub-properties in :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']`:
:php:`textfile_ext`, :php:`mediafile_ext`, or :php:`miscfile_ext`.
* Files are only accepted if their MIME type matches the expected file extension.
The MIME type is determined based on the actual file content. For example,
uploading a real PNG image with the filename `image.exe` will be rejected,
because `image/png` is not a valid MIME type for the `exe` extension.
New Configuration Property in `$GLOBALS['TYPO3_CONF_VARS']['SYS']`
------------------------------------------------------------------
A new configuration property, :php:`miscfile_ext`, has been introduced. It
allows specifying file extensions that don't belong to either `textfile_ext`
or `mediafile_ext`, such as `zip` or `xz`.
New Feature Flags
-----------------
* :php:`security.system.enforceAllowedFileExtensions`:
Controls whether only the configured file extensions are permitted.
- **Disabled by default** in existing installations.
- **Enabled by default** in new installations.
* :php:`security.system.enforceFileExtensionMimeTypeConsistency`:
Controls whether the MIME type and file extension consistency check
is enforced.
Exemptions
----------
Some use cases—such as importing files through internal low-level system
components—may require temporary exemptions from the above restrictions.
The following example shows how to define a one-time exemption for a known
and controlled operation:
.. code-block:: php
<?php
class ImportCommand
{
use \TYPO3\CMS\Core\Resource\ResourceInstructionTrait;
protected function execute(): void
{
// ...
// Skip the consistency check once for the specified storage, source, and target
$this->skipResourceConsistencyCheckForCommands($storage, $temporaryFileName, $targetFileName);
/** @var \TYPO3\CMS\Core\Resource\File $file */
$file = $storage->addFile($temporaryFileName, $targetFolder, $targetFileName);
}
}
.. index:: FAL, LocalConfiguration, ext:core
@@ -0,0 +1,54 @@
.. include:: /Includes.rst.txt
.. _important-106715-1747646438:
==================================================================================
Important: #106715 - Apply CSP sandbox mode to fileadmin's .htaccess configuration
==================================================================================
See :issue:`106715`
Description
===========
The directive `Content-Security-Policy: sandbox;` restricts
several client-side actions for files that may contain markup
(e.g., HTML, SVG):
* Disallows downloads
* Disallows form submissions
* Disallows modals and popups
* Disallows orientation and pointer lock
* Disallows presentation sessions
* Disallows navigation of the top-level browsing context
This applies only to resources located in the default file storage
location (e.g., `/fileadmin/`). Rendering Fluid templates from a
different location within the CMS application uses TYPO3s dynamic
CSP feature instead.
Since the file :file:`/fileadmin/.htaccess` is not automatically updated
once it has been created in a TYPO3 installation, maintainers must manually
adjust the web server configuration.
Below are the required changes to introduce the `sandbox` directive:
.. code-block:: diff
<IfModule mod_headers.c>
# matching requested *.pdf files only (strict rules block Safari showing PDF documents)
<FilesMatch "\.pdf$">
Header set Content-Security-Policy "default-src 'self' 'unsafe-inline'; script-src 'none'; object-src 'self'; plugin-types application/pdf;"
</FilesMatch>
# matching requested *.svg files only (allows using inline styles when serving SVG files)
<FilesMatch "\.svg">
- Header set Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'unsafe-inline'; object-src 'none';"
+ Header set Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'unsafe-inline'; object-src 'none'; sandbox;"
</FilesMatch>
# matching anything else, using negative lookbehind pattern
<FilesMatch "(?<!\.(?:pdf|svg))$">
- Header set Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'none'; object-src 'none';"
+ Header set Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'none'; object-src 'none'; sandbox;"
</FilesMatch>
.. index:: ext:install
@@ -0,0 +1,45 @@
.. include:: /Includes.rst.txt
.. _important-106735-1748270977:
========================================================
Important: #106735 - File MIME Type compatiblity mapping
========================================================
See :issue:`106735`
Description
===========
With :issue:`106240` mime type hardening has been established in order to ensure
that file extensions of uploaded files and their contents are consistent in
order to avoid sneaking in malicious files with faked file extensions or to
bypass file extension limitations.
Since PHP file detection methods can not reliable detect all IANA defined MIME
types, mime-db based heuristics are now applied to map generic MIME types like
text/plain to text/csv for `*.csv` files.
This mapping has been made adjustable for MIME types via
:php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['mimeTypeCompatibility']`
where for each generic MIME type (as detected by PHP MIME type detection) a
map from file extension to allowed concrete MIME type can be supplied.
.. code-block:: php
:caption: Configure a custom MIME type to be mapped from a detected generic type
// Example that is already shipped with TYPO3, a *.jfif file that is
// detected as image/jpeg is mapped to image/pjpeg, which is the
// defined MIME type per IANA and enforced by the FAL persistence layer.
$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['mimeTypeCompatibility']['image/jpeg']['jfif'] =
'image/pjpeg';
// Generic example, which allows a file ending in `*.foo` that is detected
// to contain text/plain contents to be mapped to the MIME type text/x-foo,
// other contents (e.g. if the file contains binary data) will not be mapped
$GLOBALS['TYPO3_CONF_VARS']['SYS']['FileInfo']['mimeTypeCompatibility']['text/plain']['foo'] =
'text/x-foo';
.. index:: FAL, ext:core
@@ -0,0 +1,39 @@
.. include:: /Includes.rst.txt
.. _important-106983-1750962567:
==================================================================
Important: #106983 - Hardened access to module-related AJAX routes
==================================================================
See :issue:`106983`
Description
===========
AJAX routes which are exclusively used in a specific backend module can now be
configured to inherit access from the respective module. A new configuration
option :php:`inheritAccessFromModule` is introduced to control this behavior.
It is already added to several existing AJAX routes shipped by TYPO3 core.
Requests to routes with an appropriate access check in place will result in a
403 response if the current backend user lacks required permissions.
Example configuration
=====================
In the following example, the `mymodule_myroute` AJAX route inherits access
checks from the `mymodule` backend module:
.. code-block:: php
:caption: EXT:my_extension/Configuration/Backend/AjaxRoutes.php
return [
'mymodule_myroute' => [
'path' => '/mymodule/myroute',
'target' => \MyVendor\MyExtension\Controller\MySpecialController::class . '::mySpecialAction',
'inheritAccessFromModule' => 'mymodule',
],
];
.. index:: Backend
@@ -0,0 +1,44 @@
.. include:: /Includes.rst.txt
.. _important-109176-1773075613:
============================================================================
Important: #109176 - CKEditor hardened iframes by enforcing sandbox behavior
============================================================================
See :issue:`109176`
Description
===========
Security-related patches from CKEditor5 v47.6.0 have been back-ported to the
TYPO3 12.4.x branch. The patches harden the usage of iframes by enforcing the
sandbox_ behaviour in the General HTML Support feature's editing area. In
TYPO3 13.4 and later, the full CKEditor5 v47.6.0 upgrade_ is used instead.
Installations that already allow iframes in their RTE configuration (e.g. for
integrating Google Maps widgets) may need to explicitly allow scripts via the
RTE YAML configuration for interactive iframes to work inside the HTML editing
area:
.. code-block:: yaml
editor:
config:
htmlSupport:
# If you already allow iframes in content area...
allow:
- { name: 'iframe', attributes: { src: true } }
# ...you may add `htmlIframeSandbox` to control the
# `<iframe sandbox="…">` when rendered by CKEditor
htmlIframeSandbox: [ 'allow-scripts', 'allow-same-origin' ]
This does not influence what is rendered in the frontend output, but only
affects the sandbox behaviour inside the CKEditor editing area.
.. _sandbox: https://ckeditor.com/docs/ckeditor5/latest/features/html/general-html-support.html#iframe-sandbox
.. _upgrade: https://ckeditor.com/blog/ckeditor-47-6-0-release-highlights/
.. index:: Backend, RTE, ext:rte_ckeditor
@@ -0,0 +1,64 @@
.. include:: /Includes.rst.txt
.. _important-96218-1733990267:
============================================================================
Important: #96218 - Use proper surrounding "html" tags for Fluid SystemEmail
============================================================================
See :issue:`96218`
Description
===========
Due to usage of :html:`data-namespace-typo3-fluid="true"` in the
:html:`<html>` declaration of the file
:file:`EXT:core/Resources/Private/Layouts/SystemEmail.html`,
the whole :html:`<html>..</html>` structure is removed from a sent
HTML mail.
Validation and possibly utilities like SpamAssassin may fail
or negatively score these mails due to these tags being missing.
Since the :html:`xmlns` declaration of the ViewHelpers is semantically
not wrong, it can actually be included in the email by removing
the :html:`data-namespace-typo3-fluid` attribute, instead of requiring
the alternate more intrusive Fluid ViewHelper declaration.
Affected installations
======================
All setups with customizations of the file
:file:`EXT:core/Resources/Private/Layouts/SystemEmail.html` for sending
FluidEmails.
Migration
=========
Adjust custom copies of the file :file:`EXT:core/Resources/Private/Layouts/SystemEmail.html`
like this:
.. code-block:: html
:caption: Before (EXT:your_extension/Resources/Private/Layouts/SystemEmail.html)
:emphasize-lines: 6
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers"
data-namespace-typo3-fluid="true">
into this:
.. code-block:: html
:caption: After (EXT:your_extension/Resources/Private/Layouts/SystemEmail.html)
:emphasize-lines: 5
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers">
.. index:: Fluid, Frontend, ext:code, NotScanned
@@ -0,0 +1,49 @@
.. include:: /Includes.rst.txt
.. _important-99781-1707215955:
========================================================================
Important: #99781 - Exporting and downloading records in the list module
========================================================================
See :issue:`99781`
Description
===========
There are two different options for exporting records in the
:guilabel:`Web->List` module.
One is using the export functionality, which is provided by EXT:impexp and is
available via the "Export" docheader button in the single table view. It is
possible to manage the display of the button using the Page TSconfig
:typoscript:`mod.web_list.noExportRecordsLinks` option. However, the export
functionality is by default disabled for non-admin users, making the button
not showing up unless the functionality is explicitly enabled for the user
with the user TSconfig :typoscript:`options.impexp.enableExportForNonAdminUser`
option.
The "Download" functionality is available via the "Download" button in each
tables header row. It is available in both, the list and also the single table
view and can be managed using the Page TSconfig
:typoscript:`mod.web_list.displayRecordDownload` option, which is enabled by
default. Next to the general option is it also possible to set this option on
a per-table basis using the
:typoscript:`mod.web_list.table.<tablename>.displayRecordDownload` option.
In case this option is set, it takes precedence over the general option.
.. code-block:: typoscript
# Page TSconfig
mod.web_list {
# Disable "Export" button in docheader
noExportRecordsLinks = 1
# Generally disable "Download" button
displayRecordDownload = 0
# Enable "Download" button for table "tt_content"
table.tt_content.displayRecordDownload = 1
}
.. index:: Backend, PHP-API, TSConfig, ext:backend
+58
View File
@@ -0,0 +1,58 @@
:template: changelogOverview.html
.. include:: /Includes.rst.txt
.. _changelog-12-4-x:
==============
12.4.x Changes
==============
**Table of contents**
.. contents::
:local:
:depth: 1
Breaking Changes
================
None since TYPO3 v12.4.0 LTS release.
.. attention::
Breaking changes are not planned after the TYPO3 v12.4.0 LTS release.
Features
========
.. toctree::
:maxdepth: 1
:titlesonly:
:glob:
Feature-*
.. attention::
New features are not planned after the TYPO3 v12.4.0 LTS release.
Deprecation
===========
.. toctree::
:maxdepth: 1
:titlesonly:
:glob:
Deprecation-*
Important
=========
.. toctree::
:maxdepth: 1
:titlesonly:
:glob:
Important-*