TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -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
|
||||
+43
@@ -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
|
||||
+37
@@ -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
|
||||
+31
@@ -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
|
||||
+69
@@ -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
|
||||
+29
@@ -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
|
||||
+56
@@ -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
|
||||
+135
@@ -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
|
||||
+53
@@ -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
|
||||
+106
@@ -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
|
||||
+106
@@ -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
|
||||
+61
@@ -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
|
||||
+45
@@ -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
|
||||
+79
@@ -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
|
||||
+54
@@ -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 TYPO3’s 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
|
||||
+39
@@ -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
|
||||
+44
@@ -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
|
||||
+64
@@ -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
|
||||
+49
@@ -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
|
||||
@@ -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-*
|
||||
Reference in New Issue
Block a user