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,38 @@
.. include:: /Includes.rst.txt
.. _deprecation-86907:
========================================================================================
Deprecation: #86907 - Deprecate usage of dependency injection with non public properties
========================================================================================
See :issue:`86907`
Description
===========
The dependency injection via properties has been marked as deprecated for all properties that are non public.
While there are several reasons not to use property injection at all there is one specific drawback with non public properties.
To be able to inject dependencies into non public properties, said properties have to be made accessible during runtime.
As that process is quite slow and expensive and non cachable, it should not be used at all.
Impact
======
Dependency injection will no longer work with non public properties.
Affected Installations
======================
All installations that use dependency injection with non public properties.
Migration
=========
The easiest, yet ugliest migration is to make the property public. If possible, switch to constructor or setter injection instead.
.. index:: PHP-API, PartiallyScanned, ext:extbase
@@ -0,0 +1,65 @@
.. include:: /Includes.rst.txt
.. _deprecation-87277:
=========================================
Deprecation: #87277 - Fluid Class Aliases
=========================================
See :issue:`87277`
Description
===========
Since introduction of the standalone package typo3fluid/fluid, the TYPO3 core provides class aliases
for the moved classes to ease usage in extensions.
These class aliases will be dropped in TYPO3 v10.
The following class aliases have been marked as deprecated and should no longer be used:
* :php:`TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler`
* :php:`TYPO3\CMS\Fluid\Core\Exception`
* :php:`TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode`
* :php:`TYPO3\CMS\Fluid\Core\Parser\InterceptorInterface`
* :php:`TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\NodeInterface`
* :php:`TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\RootNode`
* :php:`TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\ViewHelperNode`
* :php:`TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface`
* :php:`TYPO3\CMS\Fluid\Core\Variables\CmsVariableProvider`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\AbstractConditionViewHelper`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\Exception`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\Exception\InvalidVariableException`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\Facets\PostParseInterface`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\TagBuilder`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperInterface`
* :php:`TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperVariableContainer`
* :php:`TYPO3\CMS\Fluid\View\Exception`
* :php:`TYPO3\CMS\Fluid\View\Exception\InvalidSectionException`
* :php:`TYPO3\CMS\Fluid\View\Exception\InvalidTemplateResourceException`
Impact
======
Extensions and third party packages using the :php:`TYPO3\CMS\Fluid` namespace might be affected
by the stand alone Fluid package change.
If aliased class names are used, there will be fatal PHP Errors after update to TYPO3 v10.
The extension scanner will find usage of these classes.
Affected Installations
======================
All installations that use the :php:`TYPO3\CMS\Fluid` namespace for class aliases.
Migration
=========
Migrate to the original classes in namespace :php:`TYPO3Fluid\Fluid`.
.. index:: PHP-API, FullyScanned, ext:fluid
@@ -0,0 +1,26 @@
.. include:: /Includes.rst.txt
.. _feature-83334:
========================================================
Feature: #83334 - Add improved building of query strings
========================================================
See :issue:`83334`
Description
===========
The method :php:`\TYPO3\CMS\Core\Utility\HttpUtility::buildQueryString()` has been added as an enhancement to the `PHP function`_ :php:`http_build_query()`.
It implodes multidimensional parameter arrays and properly encodes parameter names as well as values to a valid query string.
with an optional prepend of :php:`?` or :php:`&` If the query is not empty, `?` or `&` are prepended in the correct sequence.
Empty parameters are skipped.
.. _`PHP function`: https://secure.php.net/manual/de/function.http-build-query.php
Impact
======
Parameter arrays can be safely transformed into HTTP GET query strings using the new method.
.. index:: PHP-API
@@ -0,0 +1,76 @@
.. include:: /Includes.rst.txt
.. _feature-86331:
====================================================
Feature: #86331 - Native URL support for MountPoints
====================================================
See :issue:`86331`
Description
===========
MountPoints allow TYPO3 editors to mount a page (and its subpages) from a different area of the site in the current page tree.
The definitions are as follows:
- MountPoint Page: A page with doktype=7 - a page pointing to a different page ("web mount")
that should act as replacement for this page and possible descendants.
- Mounted Page a.k.a. "Mount Target": A regular page containing content and subpages.
The idea behind it is to manage content only once and "link" / "mount" to a tree to be used
multiple times - while keeping the website visitor under the impression to actually
navigate just a regular subpage. There are concerns regarding SEO for having duplicate content,
but TYPO3 can be used for more than just simple websites, as Mount Points are an important tool
for heavy multi-site installations or Intranet/Extranet installations.
A MountPoint Page has the option to either display the content of the MountPoint Page itself,
or the content of the target page, when visiting this page.
Linking to a subpage will result in adding "MP" GET Parameters, and altering the root line (tree structure)
of visiting the website, as the "MP" is containing the context. The MP parameter found throughout TYPO3 Core
contains the ID of the Mounted Page and the ID of the MountPoint Page - e.g. "13-23" whereas 13 would be
the Mounted Page and 23 the MountPoint Page (doktype=7).
Recursive mount points are added to the "MP" parameter with ",", like "13-23,84-26".
Recursive mount points are defined as follows: A Mounted Page could have a subpage which in turn
has a subpage which is again a MountPoint Page.
MountPoint support is now added in TYPO3 v9 with Site Handling and slug handling.
Due to TYPO3's principles of slug handling where a page only contains one single slug
containing the URL path, and not various slugs for different places where it might be used,
TYPO3 will work by combining the slug of the MountPoint Page and a smaller part of the Mounted Page
or subpages of the Mounted Page, which will be added to the URL string - removing the necessity to actually
deal with the query parameter `MP` which will never be added again, as it is part of the URL path now.
Using MountPoint functionality on a website plays an important role for menus as this is the
only way to actually link to the subpages in a MountPoint context.
Multi-Site support:
The context for cross-domain sites is also kept, ensuring that the user will never notice that content
might be coming from a completely different site / pagetree within TYPO3.
Creating links for multi-site support is the same as if a Mounted Page is on the same site.
Impact
======
Limitations:
1. Multi-language support
Please be aware that multi-language setups are supported in general, but this would only fit if both sites support the same language IDs.
2. Slug uniqueness when using Multi-Site setups cannot be ensured
If a MountPoint Page has the slug "/more", mounting a page with "/imprint" subpage, but the MountPoint Page
has a regular sibling page with "/more/imprint" a collision cannot be detected, whereas the non-mounted page
would always work and a subpage of a Mounted Page would never be reached.
For the sake of completeness, please consider the TYPO3 documentation on the following TypoScript properties related to mount points:
- :typoscript:`config.MP_defaults`
- :typoscript:`config.MP_mapRootPoints`
- :typoscript:`config.MP_disableTypolinkClosestMPvalue`
.. index:: Frontend, ext:frontend
@@ -0,0 +1,66 @@
.. include:: /Includes.rst.txt
.. _feature-86740:
============================================
Feature: #86740 - Replace characters in slug
============================================
See :issue:`86740`
Description
===========
The configuration of the TCA type `slug` has been extended by the setting `replace`.
It allows to replace strings of a slug part.
Impact
======
Especially for enhancing the site configuration it might be useful to set the configuration.
Easy example
------------
By using the following configuration, slashes are removed from the slug.
.. code-block:: php
'type' => 'slug',
'config' => [
'generatorOptions' => [
'fields' => ['title'],
'replacements' => [
'/' => ''
],
]
'fallbackCharacter' => '-',
'prependSlash' => true,
'eval' => 'uniqueInPid'
]
Advanced examples
-----------------
The following configuration uses more replacements:
.. code-block:: php
'type' => 'slug',
'config' => [
'generatorOptions' => [
'fields' => ['title'],
'replacements' => [
'(f/m)' => '',
'/' => '-'
],
]
'fallbackCharacter' => '-',
'prependSlash' => true,
'eval' => 'uniqueInPid'
]
This will change the provided slug `Some Job in city1/city2 (f/m)` to `some-job-in-city1-city2`.
.. index:: Frontend, ext:core
@@ -0,0 +1,68 @@
.. include:: /Includes.rst.txt
.. _feature-86762:
================================================================
Feature: #86762 - Enhanced fallback modes for translated content
================================================================
See :issue:`86762`
Description
===========
Various content fallback options have been adapted to allow multiple scenarios when rendering
content in a different language than the default language (sys_language_uid=0).
The functionality of "fallbackChain" can now be defined in any kind of fallback type (see below).
The "fallbackChain" checks access / availability of a page translation of a language. If
this language does not exist, TYPO3 checks for other languages, and uses this language then
for showing content.
This results in three different kinds of rendering modes ("Fallback Type") for content in
translated pages, however it is necessary to understand the overlay concept when fetching
content in TYPO3 Frontend.
Using "language overlays" means that the default language records are fetched first.
Also, various "enable fields" (e.g. hidden / frontend user groups etc) are evaluated for the
default language. Each record then is "overlaid" with the record of the target language.
Not using "overlays" means that the default language is not considered at all.
No matter what type is chosen, records which do not have a localization parent ("l10n_parent")
will always be rendered in the target language.
The following "fallback types" exist:
1. "strict" -- Fetch the records in the default language, then overlay them with the target
language. If a record is not translated into the target language, then it is not shown at all.
This mode is typically used for 1:1 translations of fully different languages like
"English" (default) and "Danish" (translation).
2. "fallback" -- Fetch records from default language, and checks for a translation of
each record. If the record has no translation, the default language is shown.
This scenario is usually used when the default language is "German" but the translation
is "Swiss-German" where only different content elements are translated, but the rest is
a 1:1 translation.
3. "free" (new) -- Fetch all records from the target language directly without worrying about
the default language at all.
This is typically the case when a localized page may have fully different content than the
default language. E.g. "English" as default language, but only the most important content parts
are added in language "Swahili".
Impact
======
Existing installations with site configuration "fallback" will now render the non-translated
content (un-localized records), too.
Regardless of the fallback type, records without localization parent, and records set to "-1"
(All Languages) are always fetched.
.. index:: Frontend
@@ -0,0 +1,55 @@
.. include:: /Includes.rst.txt
.. _feature-86826:
==========================================
Feature: #86826 - Recursive record sitemap
==========================================
See :issue:`86826`
Description
===========
The class :php:`TYPO3\CMS\Seo\XmlSitemap\RecordsXmlSitemapDataProvider` supports now the configuration `recursive` to include
records not only from provided list of page ids but also its subpages.
:typoscript:`recursive` refers to the number of levels taken into account beyond the `pid` page. (default: 0)
Impact
======
A full example:
.. code-block:: typoscript
plugin.tx_seo {
config {
xmlSitemap {
sitemaps {
news {
provider = TYPO3\CMS\Seo\XmlSitemap\RecordsXmlSitemapDataProvider
config {
table = tx_news_domain_model_news
sortField = sorting
lastModifiedField = tstamp
pid = 26
recursive = 2
url {
pageId = 25
fieldToParameterMap {
uid = tx_news_pi1[news]
}
additionalGetParameters {
tx_news_pi1.controller = News
tx_news_pi1.action = detail
}
useCacheHash = 1
}
}
}
}
}
}
.. index:: Frontend, ext:seo
@@ -0,0 +1,28 @@
.. include:: /Includes.rst.txt
.. _feature-86881:
============================================================
Feature: #86881 - Support of Features in expression language
============================================================
See :issue:`86881`
Description
===========
Support for feature toggle check in the symfony expression language DefaultFunctionProvider is provided.
With the new function :typoscript:`feature()` the feature toggle can be checked.
.. code-block:: typoscript
[feature("TypoScript.strictSyntax")]
# This condition matches if the feature toggle "TypoScript.strictSyntax" is true
[END]
[feature("TypoScript.strictSyntax") === false]
# This condition matches if the feature toggle "TypoScript.strictSyntax" is false
[END]
.. index:: Backend, Frontend, TypoScript, ext:core
@@ -0,0 +1,35 @@
.. include:: /Includes.rst.txt
.. _feature-86973:
==========================================================
Feature: #86973 - TypoScript getText property siteLanguage
==========================================================
See :issue:`86973`
Description
===========
Site language configuration can now be accessed via the :typoscript:`getText` property :typoscript:`siteLanguage`
in TypoScript.
Examples:
.. code-block:: typoscript
page.10 = TEXT
page.10.data = siteLanguage:navigationTitle
page.10.wrap = This is the title of the current site language: |
.. code-block:: typoscript
page.10 = TEXT
page.10.dataWrap = The current site language direction is {siteLanguage:direction}
Impact
======
Accessing the current site language configuration is now possible in TypoScript.
.. index:: PHP-API, ext:frontend
@@ -0,0 +1,46 @@
.. include:: /Includes.rst.txt
.. _feature-87033:
===================================================================
Feature: #87033 - New TypoScript Property config.htmlTag.attributes
===================================================================
See :issue:`87033`
Description
===========
The new site handling functionality adds some attributes to the frontend rendering <html> tag automatically, even per language
(e.g. "lang" and "dir" attributes) without having to use TypoScript anymore.
However, if custom properties should be added, e.g. :html:`<html lang="fr" amp>`, this is not possible anymore without having
to reintroduce TypoScript conditions or complex stdWrap functionality. In previous versions the property :typoscript:`config.htmlTag_setParams`
was used to override all properties, but since there were conditions in place for languages, this was a one-liner change per language.
In order to use the full power of TypoScript flexibility, it is possible now to use :typoscript:`config.htmlTag.attributes` which
allows to override and add custom attributes via TypoScript without having to re-add the existing attributes generated by SiteHandling.
This property supersedes the previous :typoscript:`config.htmlTag_setParams` option by providing a more flexible API to add attributes.
Examples:
:typoscript:`config.htmlTag.attributes.class = no-js`
Will result in :html:`<html lang="fr" class="no-js">`.
It is even possible to add attributes without a value:
:typoscript:`config.htmlTag.attributes.amp =`
will render :html:`<html lang="it" amp>`
Please note that "lang" attribute in these examples are auto-generated by Site configuration, depending on the value added there.
Impact
======
If the TypoScript option :typoscript:`config.htmlTag.attributes` is used, then :typoscript:`config.htmlTag_setParams` has no effect anymore.
.. index:: TypoScript, ext:frontend
@@ -0,0 +1,70 @@
.. include:: /Includes.rst.txt
.. _feature-87085:
==================================================
Feature: #87085 - Fallback options for slug fields
==================================================
See :issue:`87085`
Description
===========
In case of SEO optimizations and the daily work of an editor, now it is possible to define a list of fields in the slug
configuration as nested array:
.. code-block:: php
'columns' => [
'slug' => [
'config' => [
'generatorOptions' => [
// use value of 'nav_title'. If 'nav_title' is empty, use value of 'title'
'fields' => [['nav_title', 'title']]
]
]
],
]
The fallback field can also be combined with other fields:
.. code-block:: php
'columns' => [
'slug' => [
'config' => [
'generatorOptions' => [
// Concatenate path segments. In first segment, use 'nav_title' or 'title'.
'fields' => [['nav_title', 'title'], 'other_field']
]
]
],
]
Hint
----
In this context:
* :php:`['nav_title', 'title']` is the same as :php:`[['nav_title'], ['title']]`
* :php:`['nav_title', 'title']` is **not** the same as :php:`[['nav_title', 'title']]`
Examples
--------
+-----------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+
| Configuration value | Values of an example page record | Resulting slug |
+=================================================================+======================================================================================================================================+===================================+
|:php:`[['nav_title', 'title']]` | :php:`['title' => 'Products', 'nav_title' => '']` | `/products` |
+-----------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+
|:php:`[['title', 'subtitle']]` | :php:`['title' => 'Products', 'subtitle' => 'Product subtitle']` | `/products` |
+-----------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+
|:php:`['title', 'subtitle']` or :php:`[['title'], ['subtitle']]` | :php:`['title' => 'Products', 'subtitle' => 'Product subtitle']` | `/products/product-subtitle` |
+-----------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+
|:php:`['nav_title', 'title'], 'subtitle'` | :php:`['title' => 'Products', 'nav_title' => 'Best products', 'subtitle' => 'Product subtitle']` | `/best-products/product-subtitle` |
+-----------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+
|:php:`['seo_title', 'title'], ['nav_title', 'subtitle']` | :php:`['title' => 'Products', 'nav_title' => 'Best products', 'subtitle' => 'Product subtitle', 'seo_title' => 'SEO product title']` | `/seo-product-title/products` |
+-----------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+
.. index:: TCA
@@ -0,0 +1,26 @@
.. include:: /Includes.rst.txt
.. _feature-87380:
========================================================================================
Feature: #87380 - Introduce SiteLanguageAwareInterface to denote site language awareness
========================================================================================
See :issue:`87380`
Description
===========
A `SiteLanguageAwareInterface` with the methods `setSiteLanguage(Entity\SiteLanguage $siteLanguage)`
and `getSiteLanguage()` has been introduced. The interface can be used to denote a class as aware of
the site language.
Impact
======
Routing aspects respecting the site language are now using the `SiteLanguageAwareInterface` in addition
to the `SiteLanguageAwareTrait`. The `AspectFactory` check has been adjusted to check for the interface
_or_ the trait. If you are currently using the trait, you should implement the interface as well.
.. index:: PHP-API, ext:core
@@ -0,0 +1,56 @@
.. include:: /Includes.rst.txt
.. _feature-87610:
===========================================================================
Feature: #87610 - New FAL API to search for files including their meta data
===========================================================================
See :issue:`87610`
Description
===========
A new API is introduced to search for files in a storage or folder, which includes matches in meta data of those files.
The given search term is looked for in all search fields defined in TCA of `sys_file` and `sys_file_metadata` tables.
A new driver capability :php:`\TYPO3\CMS\Core\Resource\ResourceStorageInterface::CAPABILITY_HIERARCHICAL_IDENTIFIERS`
is introduced to allow implementing an optimized search with good performance.
Drivers can optionally add this capability in case the identifiers that are constructed by the driver
include the directory structure.
Adding this capability to drivers can provide a big performance boost
when it comes to recursive search (which is default in the file list and file browser UI).
Impact
======
This change is fully backwards compatible. Custom driver implementations will continue to work like before,
but they won't benefit from the performance gain unless the new capability is added.
Searching for files in a folder works like this:
.. code-block:: php
$searchDemand = FileSearchDemand::createForSearchTerm($searchWord)->withRecursive();
$files = $folder->searchFiles($searchDemand);
Searching for files in a complete storage works like this:
.. code-block:: php
$searchDemand = FileSearchDemand::createForSearchTerm($searchWord)->withRecursive();
$files = $storage->searchFiles($searchDemand);
It is possible to further limit the result set, by adding additional restrictions to :php:`TYPO3\CMS\Core\Resource\Folder\FileSearchDemand`.
Please note, that :php:`TYPO3\CMS\Core\Resource\Folder\FileSearchDemand` is an immutable value object, but allows chaining methods for ease of use:
.. code-block:: php
$searchDemand = FileSearchDemand::createForSearchTerm($this->searchWord)
->withRecursive()
->withMaxResults(10)
->withOrdering('fileext');
$files = $storage->searchFiles($searchDemand);
.. index:: Backend, PHP-API, ext:filelist
@@ -0,0 +1,35 @@
.. include:: /Includes.rst.txt
.. _feature-87748:
===================================
Feature: #87748 - Add SiteProcessor
===================================
See :issue:`87748`
Description
===========
A new Site Processor :php:`TYPO3\CMS\Frontend\DataProcessing\SiteProcessor` has been introduced which can be used to fetch data from the site entity.
.. code-block:: typoscript
tt_content.mycontent.20 = FLUIDTEMPLATE
tt_content.mycontent.20 {
file = EXT:myextension/Resources/Private/Templates/ContentObjects/MyContent.html
dataProcessing.10 = TYPO3\CMS\Frontend\DataProcessing\SiteProcessor
dataProcessing.10 {
as = site
}
}
In the Fluid template the properties of the site entity can be accessed
.. code-block:: html
<p>{site.rootPageId}</p>
<p>{site.someCustomConfiguration}</p>
.. index:: Fluid, Frontend, ext:frontend
@@ -0,0 +1,56 @@
.. include:: /Includes.rst.txt
.. _feature-88198:
=========================================================
Feature: #88198 - TCA-based Slug modifiers for extensions
=========================================================
See :issue:`88198`
Description
===========
The new "slug" TCA type now includes a possibility to hook into the generation of a slug via custom TCA generation options.
Hooks can be registered via
.. code-block:: php
$GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config']['generatorOptions']['postModifiers'][] = My\Class::class . '->method';
in :file:`EXT:myextension/Configuration/TCA/Overrides/$tableName.php`, where $tableName can be a table like `pages` and
`$fieldName` matches the slug field name, e.g. `slug`.
Example:
.. code-block:: php
$GLOBALS['TCA']['pages']['columns']['slug']['config']['generatorOptions']['postModifiers'][] = My\Class::class . '->modifySlug';
The method then receives a parameter array with the following values:
.. code-block:: php
[
'slug' ... the slug to be used
'workspaceId' ... the workspace ID, "0" if in live workspace
'configuration' ... the configuration of the TCA field
'record' ... important fields of the record (available fields might differ from usage type)
'pid' ... the resolved parent page ID
'prefix' ... the prefix that was added
'tableName' ... the table of the slug field
'fieldName' ... the field name of the slug field
];
All hooks need to return the modified slug value.
Impact
======
Any extension can modify a specific slug, for instance only for a specific part of the page tree.
It is also possible for extensions to implement custom functionality like "Do not include in slug generation" as known from RealURL.
.. index:: TCA
@@ -0,0 +1,26 @@
.. include:: /Includes.rst.txt
.. _feature-89526:
===================================================
Feature: #89526 - FeatureFlag: newTranslationServer
===================================================
See :issue:`89556`
Description
===========
The feature switch `newTranslationServer` makes it possible for installations to fetch translations from the new translation server.
The new translation server is building labels from Crowdin (https://crowdin.com/project/typo3-cms) instead of the previous translation server based on Pootle (https://translation.typo3.org/).
If you are interested in this topic, join the Crowdin Initiative. All information can be found at https://typo3.org/community/teams/typo3-development/initiatives/localization-with-crowdin/.
It is very simple to provide translations by registering at Crowdin and suggest translations online.
Impact
======
The feature is enabled by default for new installations.
.. index:: Backend, Frontend, ext:core
@@ -0,0 +1,16 @@
.. include:: /Includes.rst.txt
.. _feature-90328:
============================================
Feature: #90328 - Support of Macedonian (MK)
============================================
See :issue:`90328`
Description
===========
TYPO3 supports now localizations into Macedonian which uses `mk` as locale.
.. index:: ext:core
@@ -0,0 +1,36 @@
.. include:: /Includes.rst.txt
.. _feature-91354:
===========================================================
Feature: #91354 - Integrate server response security checks
===========================================================
See :issue:`91354`
Description
===========
In order to evaluate potential server misconfigurations and to reduce
the potential of security implications in general, a new HTTP response
check is integrated to "Environment Status" and the "Security" section
in the reports module.
Impact
======
It is evaluated whether non-standard file extensions lead to unexpected
handling on the server-side, such as `test.php.wrong` being evaluated
as PHP or `test.html.wrong` being served with `text/html` content type.
Besides that, HTTP host header injection is evaluated. In case `HTTP_HOST` or
`SERVER_NAME` were reported to contain unexpected values, this is an indicator
for being affected by this configuration flaw. For Apache web servers, using the
configuration directive `UseCanonicalName On` might solve this problem.
Details are explained in `TYPO3 Security Guidelines for Administrators`_.
.. _TYPO3 Security Guidelines for Administrators: https://docs.typo3.org/m/typo3/reference-coreapi/10.4/en-us/Security/GuidelinesAdministrators/Index.html#file-extension-handling
.. index:: ext:install
@@ -0,0 +1,70 @@
.. include:: /Includes.rst.txt
.. _feature-94825-1667998632:
======================================================
Feature: #94825 - New f:sanitize.html Fluid ViewHelper
======================================================
See :issue:`94825`
Description
===========
A new Fluid ViewHelper :html:`<f:sanitize.html>` is available
for use in any Fluid Template.
Unlike :html:`<f:format.html>` the new ViewHelper does not fully rewrite
the contents of the ViewHelper, but only cleans the HTML for
incorrect / possibly bad code.
The htmlSanitize keeps all HTML code as is, but cleans up invalid
and malicious code based on the third-party package `typo3/html-sanitize`.
An optional view-helper argument `build` allows using a defined preset, or a
fully qualified class name of a builder instance as alternative, which has
to implement :php:`\TYPO3\HtmlSanitizer\Builder\BuilderInterface`.
If not given, the configuration falls back to the best-practice
sanitization preset for TYPO3's base RTE configuration (called "default").
Impact
======
The "default" preset of :html:`<f:sanitize.html>` allows
to explicitly sanitize user-submitted markup - for instance provided in
rich-text input fields using the TYPO3 backend user interface. The
default preset only supports common HTML tags and attributes that usually are
expected to be safe - for instance :html:`<iframe>`, :html:`<form>`, :html:`<nav>` or
similar elements are not supported (currently) and not supposed to be defined
by users or editors, but rather by the actual HTML Template which shouldn't
be fully wrapped in :html:`<f:sanitize.html>`.
When to use the different ViewHelpers:
* :html:`<f:format.html>`
Use this for wrapping fields produced by RTE fields, which parses
HTML and adds attributes, replaces TYPO3-internal links to pages or files,
based on :typoscript:`lib.parseFunc_RTE`. For this reason, it is recommended to use
this ViewHelper mainly in Frontend rendering.
This ViewHelper calls TYPO3's "parseFunc", which means that `htmlSanitize` is
activated by default in TYPO3 installations.
Summarized: :html:`<f:format.html>` does HTML sanitization plus rebuilding
the HTML output based on the configuration from `lib.parseFunc`.
* :html:`<f:sanitize.html>`
This ViewHelper takes the HTML as is, and removes malicious HTML code. This is
useful for HTML returned from external sources where the HTML-based content is
untrusted. It can be used in Frontend and Backend environments.
* :html:`<f:format.raw>`
This ViewHelper just outputs the content as is, including all HTML. Use this
ViewHelper only if the content can be fully trusted.
All of the ViewHelpers above do not escape any of the contents.
.. index:: Fluid, ext:fluid
@@ -0,0 +1,30 @@
.. include:: /Includes.rst.txt
.. _important-65636:
==========================================================================
Important: #65636 - File meta data can now be edited on read only storages
==========================================================================
See :issue:`65636`
Description
===========
Whether meta data editing of files is allowed or not must not be bound to whether a file is
physically writable in a storage, or whether the storage itself is set read only.
Editing meta data should on the other hand be forbidden, when the file is within a read only
file mount.
Allowing meta data editing on read only storage
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To allow to distinguish between read access to a file and write access to file meta data,
a new file action permission `editMeta` is introduced, which is automatically checked and
enforced when saving a meta data record.
When having to check for editing meta data permission in extension code, it is recommended
to use the new file action permission instead of the previously used permission `read`.
.. index:: ext:core
@@ -0,0 +1,20 @@
.. include:: /Includes.rst.txt
.. _important-76166:
==============================================================
Important: #76166 - X-UA-Compatible not set in backend anymore
==============================================================
See :issue:`76166`
Description
===========
As the official recommendation of Microsoft regarding the X-UA-Compatible tag is to not set this in the HTML code but
instead via server configuration, the tag is not rendered by default in the backend anymore.
The TYPO3 default :file:`.htaccess` and :file:`web.config` files already contain the corresponding settings.
If you are using Internet Explorer configured to use compat mode by default, you may need to set these settings to ensure `edge` mode.
.. index:: Backend, ext:backend
@@ -0,0 +1,49 @@
.. include:: /Includes.rst.txt
.. _important-84105:
=======================================================
Important: #84105 - Streamline deprecation log handling
=======================================================
See :issue:`84105`
Description
===========
TYPO3 now comes with default configuration, in which deprecation logging is disabled.
This means if you update to the latest TYPO3 version, you need to change your development
configuration to enable deprecation logging in case you need it.
Enabling the deprecation log can be done in Install Tool. Navigate to "Settings",
click on "Choose Preset" in "Configuration Presets" pane, open "Debug Settings", select "Debug"
and submit with "Activate preset".
Disabling deprecation log can be done by selecting the "Live" preset instead.
Please note, that these steps only enable/disable the FileWriter, which comes with TYPO3 default configuration.
If you manually configured **additional** writers for the `TYPO3.CMS.deprecations` logger, you need to manually remove
them to completely disable deprecation logging.
This is how the LOG section in :file:`LocalConfiguration.php` looks like with disabled deprecation logging:
.. code-block:: php
'LOG' => [
'TYPO3' => [
'CMS' => [
'deprecations' => [
'writerConfiguration' => [
\TYPO3\CMS\Core\Log\LogLevel::NOTICE => [
\TYPO3\CMS\Core\Log\Writer\FileWriter::class => [
'disabled' => true,
],
],
],
],
],
],
],
Any other log writer can be disabled as well, by providing a `disabled` option with a truthy value.
.. index:: LocalConfiguration, ext:core
@@ -0,0 +1,26 @@
.. include:: /Includes.rst.txt
.. _important-84985:
======================================================================
Important: #84985 - Unified Workspace Restriction for Database Queries
======================================================================
See :issue:`84985`
Description
===========
A new :php:`WorkspaceRestriction` is added to overcome certain downsides of the existing
:php:`FrontendWorkspaceRestriction` and :php:`BackendWorkspaceRestriction`. The new workspace restriction
limits a SQL query to only select records which are "online" (pid != -1) and in live or current
workspace.
As an important note and limitation of any workspace-related restrictions, fetching the exact
records need to be handled after the SQL results are fetched, by overlaying the records with
:php:`BackendUtility::getRecordWSOL()`, :php:`PageRepository->versionOL()` or :php:`PlainDataResolver`.
For now, the :php:`WorkspaceRestriction` must be used explicitly in various contexts and is not applied
automatically.
.. index:: Database, PHP-API
@@ -0,0 +1,46 @@
.. include:: /Includes.rst.txt
.. _important-86577:
===========================================================================
Important: #86577 - Query parameters are now included in canonicalized URLs
===========================================================================
See :issue:`86577`
Description
===========
Canonicalized URLs include all query parameters which are needed to define what content to show
on a page. These URLs are used for the canonical URL and the hreflang URLs.
This is especially important with for example detail pages of records. The query parameters are
crucial to show the right content.
Possibility to define query parameters to be included in canonicalized URLs
---------------------------------------------------------------------------
By default only parameters that are needed to calculate the cHash are included in the
canonicalized URLs. If you want to add your own parameters that should be included in those
URLs, you can use the newly introduced configuration option
:php:`$GLOBALS['TYPO3_CONF_VARS']['FE']['additionalCanonicalizedUrlParameters']`. You can add
your own query parameters by adding them as elements of the array.
An example:
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['FE']['additionalCanonicalizedUrlParameters'] => [
'queryParam1',
'queryParam2',
]
This example will add query parameters :html:`queryParam1` and :html:`queryParam2` to the canonicalized
URLs if they are provided.
.. important::
Be careful when adding your own parameters. Only add those parameters which will change the
content of your page. Otherwise search engines will most likely indicate your pages as
duplicate content.
.. index:: ext:seo, ext:frontend, PHP-API
@@ -0,0 +1,36 @@
.. include:: /Includes.rst.txt
.. _important-86785:
================================================================================
Important: #86785 - Exclude logger from serialisation on save for scheduler task
================================================================================
See :issue:`86785`
Description
===========
Calling the scheduler command on CLI or in backend throws an error, when you
created a scheduler task in one environment (for example one where TYPO3 was
running in `/var/www/html`) - and then you take that database and move to another
environment (where TYPO3 is running somewhere else, for example in
`/var/www/something`). Trying to execute any task in the scheduler resulted
in an error, because the Logger instance that was stored with the task in the
database had the wrong log file path.
To get rid of that problem, the logger is no longer stored with the task in the
database, but instead re-instantiated when the task is run
(which means it checks for correct paths on the current environment).
Exclusion of the logger instance from the record during save to database
prevents the error.
Impact
======
The stored and serialized tasks from upgraded TYPO3 instances and new saved tasks still work as before.
The logger instance is initialized while running the scheduler task and is not saved to the serialized task
object anymore. The logger (FileWriter::class) can open and write the log file to the current environment paths.
.. index:: Backend, ext:scheduler
@@ -0,0 +1,53 @@
.. include:: /Includes.rst.txt
.. _important-86895:
===================================================================
Important: #86895 - Route aspects take precedence over requirements
===================================================================
See :issue:`86895`
Description
===========
Route `requirements` are ignored for route variables having a corresponding
setting in `aspects`. Imagine there would be an aspect that is mapping internal
value `1` to route value `one` and vice verse - it is not possible to explicitly
define the `requirements` for this case - which is why `aspects` take precedence.
The following example illustrates the mentioned dilemma between route generation
and resolving:
.. code-block:: yaml
routeEnhancers:
MyPlugin
type: 'Plugin'
namespace: 'my'
routePath: 'overview/{month}'
requirements:
# note: it does not make any sense to declare all values here again
month: '^(\d+|january|february|march|april|...|december)$'
aspects:
month:
type: 'StaticValueMapper'
map:
january: '1'
february: '2'
march: '3'
april: '4'
may: '5'
june: '6'
july: '7'
august: '8'
september: '9'
october: '10'
november: '11'
december: '12'
Actually the `map` in the previous example is already defining all valid values.
That's why actually `aspects` take precedence over `requirements` for a specific
`routePath` definition.
.. index:: Frontend, ext:core
@@ -0,0 +1,23 @@
.. include:: /Includes.rst.txt
.. _important-86994:
======================================================================
Important: #86994 - Indexed Search indexes pages using route enhancers
======================================================================
See :issue:`86994`
Description
===========
Because of pages that use route enhancers do not use `cHash` functionality in most cases, it is necessary to add the
static arguments of the indexed page to generate the phash values used by `indexed_search`.
For administration of the indexed pages, the static arguments of the page need to be stored in the `index_phash`
database table as well, which makes their enhancing inevitable.
In order to make indexed search work with Site Handling, update database schema using the Database Analyzer in maintenance
module to add the necessary database field. Once done, the search index needs to be rebuilt.
.. index:: Backend, Database, Frontend, ext:indexed_search
@@ -0,0 +1,37 @@
.. include:: /Includes.rst.txt
.. _important-87028:
===========================================================================
Important: #87028 - Access objects from `ObjectStorage` using numeric value
===========================================================================
See :issue:`87028`
Description
===========
It is now possible to access the objects of an instance of :php:`TYPO3\CMS\Extbase\Persistence\ObjectStorage` using a numeric value.
The following code now works:
.. code-block:: php
$objectStorage = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
$objectStorage->attach(new \stdClass());
$myObject = $objectStorage->offsetGet(0);
And more importantly, the following Fluid code works as well:
.. code-block:: html
<f:image image="{myObject.resources.0}" alt="My image!" />
Impact
======
The old way of getting information of an object in the storage still works as before.
.. index:: Fluid, PHP-API, ext:extbase
@@ -0,0 +1,41 @@
.. include:: /Includes.rst.txt
.. _important-87518:
=====================================================================
Important: #87518 - Use prepared statements for pdo_mysql per default
=====================================================================
See :issue:`87518`
Description
===========
Before this adaption, the `pdo_mysql` driver used emulated prepared statements per default.
With that, all returned values of a query were strings.
With this change the behavior changes to use the actual prepared statements,
which return native data types. Thus, if a column is defined as INTEGER,
the returned value in PHP will also be an INTEGER.
It is possible to deactivate this feature as follows:
You need to "overwrite" the option to set `PDO::ATTR_EMULATE_PREPARES`
(reference: https://www.php.net/manual/en/pdo.setattribute.php) in your database connection:
.. code-block:: php
'Connections' => [
'Default' => [
'dbname' => 'some_database_name',
'driver' => 'pdo_mysql',
'driverOptions' => [
\PDO::ATTR_EMULATE_PREPARES => true
],
'password' => 's0meS3curePW!',
'user' => 'someUser',
],
],
.. index:: Database, ext:core
@@ -0,0 +1,36 @@
.. include:: /Includes.rst.txt
.. _important-87980:
======================================================================
Important: #87980 - "Page is being generated" message has been removed
======================================================================
See :issue:`87980`
Description
===========
The "Page is being generated" message and the corresponding
temporary 503 response have been removed.
Instead of offloading the work to wait for the final page content,
concurrent requests now wait for the real page content to be
rendered (and deliver the content from cache once ready) instead
of sending a 503 response code and the famous "Page is being
generated" message.
The motivation for this change:
The 503 status code together with the "Page is being generated message"
does not only occur for slow or high traffic sites. It will be displayed
even for two concurrent requests, no matter how fast the page rendered
or how low the current traffic is.
The requests only need to (nearly) arrive at the same time.
Note: In case the increased number of waiting requests has a negative
impact on highly frequented servers, an additional proxy cache should be
considered in front of the server to make sure clients are served a valid
response without waiting until new content is ready.
.. index:: Frontend, ext:frontend
@@ -0,0 +1,32 @@
.. include:: /Includes.rst.txt
.. _important-88045:
======================================================
Important: #88045 - Locales dependencies configuration
======================================================
See :issue:`88045`
Description
===========
Due to a bug in :php:`TYPO3\CMS\Extbase\Utility\LocalizationUtility` the configured dependencies for
a (custom) locale were not taken into account.
One could circumvent this bug by declaring the following configuration as a workaround:
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['dependencies'] = [
'de_AT' => [
['de']
]
];
Since this bug now has been fixed, installations using these kinds of workaround need to update
their configuration as described in the `official documentation`_.
.. _`official documentation`: https://docs.typo3.org/m/typo3/reference-coreapi/9.5/en-us/ApiOverview/Internationalization/ManagingTranslations.html#custom-languages
.. index:: Frontend, ext:extbase
@@ -0,0 +1,26 @@
.. include:: /Includes.rst.txt
.. _important-88720:
======================================================
Important: #88720 - Respect site for persisted mappers
======================================================
See :issue:`88720`
Description
===========
:php:`\TYPO3\CMS\Core\Routing\Aspect\AspectFactory::createAspects()` signature
requires was extended with mandatory argument `\TYPO3\CMS\Core\Site\Entity\Site $site`
and is now defined like
.. code-block:: php
public function createAspects(array $aspects, SiteLanguage $language, Site $site): array
Extensions using :php:`\TYPO3\CMS\Core\Routing\Aspect\AspectFactory::createAspects()`
have to be upgraded to pass all mandatory arguments.
.. index:: Backend, Frontend, PHP-API, FullyScanned
@@ -0,0 +1,26 @@
.. include:: /Includes.rst.txt
.. _important-88824:
=====================================================
Important: #88824 - Add cache for error page handling
=====================================================
See :issue:`88824`
Description
===========
In order to prevent possible DoS attacks when the page-based error handler
is used, the content of the 404 error page is now cached in the TYPO3
page cache. Any dynamic content on the error page (e.g. content created
by TypoScript or uncached plugins) will therefore also be cached.
If the 404 error page contains dynamic content, TYPO3 administrators must
ensure that no sensitive data (e.g. username of logged in frontend user)
will be shown on the error page.
If dynamic content is required on the 404 error page, it is recommended
to implement a custom PHP based error handler.
.. index:: Backend, ext:backend
@@ -0,0 +1,27 @@
.. include:: /Includes.rst.txt
.. _important-89269:
===================================================================================
Important: #89269 - Introduce Upgrade Wizard for invalid Backend User configuration
===================================================================================
See :issue:`89269`
Description
===========
Each database record in table `be_users` stores an individual user configuration in
the field `uc`. It is exposed during runtime in :php:`$GLOBALS['BE_USER']->uc`.
In older TYPO3 versions serialized class instances of :php:`\stdClass` have been
persisted to mentioned field - which is not possible anymore since TYPO3 v9.
A corresponding upgrade wizard **"Update backend user configuration array"**
aims to convert :php:`\stdClass` data to plain PHP arrays using scalar values.
Since this upgrade wizard was introduced late with TYPO3 v9.5.11 it is suggested
to make sure this upgrade step is executed in case a website has been updated
before (e.g. from TYPO3 v8 to TYPO3 v9.5.1).
.. index:: Backend, Database, ext:install
@@ -0,0 +1,33 @@
.. include:: /Includes.rst.txt
.. _important-90911:
================================================================
Important: #90911 - Package algo26-matthias/idna-convert removed
================================================================
See :issue:`90911`
Description
===========
The TYPO3 core dependency / composer library `algo26-matthias/idna-convert` does not support PHP 7.4
in its currently used version. It has been removed from the composer dependencies and the current used
code is placed into `typo3/sysext/core/Resources/PHP/idna-converter` to support directly usage of
that package.
This makes it possible to use TYPO3 v9 with umlaut domain validation (e.g. also when using EXT:form
with sending an email to someone with a umlaut domain as recipient) in conjunction with TYPO3 v9 and
PHP 7.4.
If the PHP code of the package is used directly by third-party extensions, this will have no further
side effects, as the TYPO3 core still provides the source code, but be aware will not work with
PHP 7.4.
If you like to use the package in a newer version, follow the docs https://idnaconv.net/docs.html
and add the custom PHP code yourself.
If you are using the TYPO3 API `GeneralUtility::idnaEncode()` everything works as before, but now
also with PHP 7.4 support.
.. index:: PHP-API, ext:core
@@ -0,0 +1,66 @@
.. include:: /Includes.rst.txt
.. _important-91242:
==========================================================
Important: #91242 - Introduce Backend Route Referrer Check
==========================================================
See :issue:`91242`
Description
===========
Public backend routes (those having option :php:`'access' => 'public'` in
:file:`Configuration/Backend/Routes.php`) do not require any session token,
but can be used to internally redirect to a route that requires a session
token. For this context it is required that a backend user is currently
logged in having a valid session.
This scenario can lead to situations that an existing cross-site scripting
vulnerability (XSS) allows to bypass mentioned session token - which can be
considered as cross-site request forgery (CSRF).
The difference in terminology is that this scenario occurs on same-site
requests and not cross-site - however, potential security implications are
still the same.
In order to mitigate described potential backend routes can enforce the
existence of a HTTP `Referer` header by adding new option `referrer` to
routes in :file:`Configuration/Backend/Routes.php`.
.. code-block:: php
'main' => [
'path' => '/main',
'referrer' => 'required,refresh-empty',
'target' => Controller\BackendController::class . '::mainAction'
],
Values for option `referrer` are declared as comma-separated list:
* `required` enforces existence of HTTP `Referer` header that has to match the
currently used backend URL (e.g. `https://example.org/typo3/`), the request
will be denied otherwise.
* `refresh-empty` triggers a HTML based refresh in case HTTP `Referer` header
is not given or empty - this attempt uses an HTML refresh, since regular HTTP
`Location` redirect still would not set a referrer. It implies this technique
should only be used on plain HTML responses and won't have any impact e.g. on
JSON or XML response types.
This technique should be used on all public routes (without session token) that
internally redirect to a restricted route (having a session token). The goal is
to protect and keep information about the current session token internal.
The request sequence in the TYPO3 core looks like this:
* HTTP request to `https://example.org/typo3/` having a valid user session
* internally **public** backend route `/login` is processed
* internally redirects to **restricted** backend route `/main` since an
existing and valid backend user session was found
+ HTTP redirect to `https://example.org/typo3/index.php?route=/main&token=...`
+ exposing the token is mitigated with `referrer` route option mentioned above
Please keep in mind these steps are part of a mitigation strategy, which requires
to be aware of mentioned implications when implementing custom web applications.
.. index:: Backend, PHP-API, ext:backend
@@ -0,0 +1,64 @@
.. include:: /Includes.rst.txt
.. _important-92836:
=============================================================================
Important: #92836 - Introduce sudo mode for Install Tool accessed via backend
=============================================================================
See :issue:`92836`
Description
===========
When accessing the Install Tool via backend user interface, currently logged in
backend users have to confirm their user password again in order to get access
to the Install Tool. As an alternative, it is also possible to use the install
tool password (reasons described below in "side effects" section). This is done
in order to mitigate unintended modifications that might occur as result
of e.g. possible cross-site scripting vulnerabilities in the system.
Standalone Install Tool is not affected by sudo mode confirmation.
This change enforces mitigation as mentioned in TYPO3-CORE-SA-2020-006_.
Potential side effects
======================
Albeit default local authentication mechanisms are working well, there are
side effects for 3rd party extensions that make use of these `auth` service
chains as well - such as multi-factor authentication or single sign-on handling.
As an alternative, it is possible to confirm actions using the Install Tool
password, instead of confirming with users' password (which might be handled
with separate remote services).
Services that extend authentication with custom additional factors (2FA/MFA)
are advised to intercept only valid login requests instead of all `authUser`
invocations.
.. code-block:: php
class MyAuthenticationService
extends \TYPO3\CMS\Core\Authentication\AbstractAuthenticationService
{
public function authUser(array $user)
{
// only handle actual login requests
if (empty($this->login['status'])
|| $this->login['status'] !== 'login') {
// skip this service, hand over to next in chain
return 100;
}
...
// usual processing for valid login requests
...
}
}
Please see this pull-request_ for a 2FA/MFA extension as an example.
.. _TYPO3-CORE-SA-2020-006: https://typo3.org/security/advisory/typo3-core-sa-2020-006
.. _pull-request: https://github.com/derhansen/sf_yubikey/pull/45/files
.. index:: Backend, ext:install
@@ -0,0 +1,220 @@
.. include:: /Includes.rst.txt
.. _important-94484:
============================================
Important: #94484 - Introduce HTML Sanitizer
============================================
See :issue:`94484`
Description
===========
To sanitize and purge XSS from markup during frontend rendering, new
custom HTML sanitizer has been introduced, based on `masterminds/html5`.
Both :php:`\TYPO3\HtmlSanitizer\Builder\CommonBuilder` and
:php:`\TYPO3\HtmlSanitizer\Visitor\CommonVisitor` provide common configuration
which is in line with expected tags that are allowed in backend RTE.
Using a custom builder instance, it is possible to adjust for individual
demands - however, configuration possibilities cannot be modified using
TypoScript - basically since the existing syntax does not cover all
necessary scenarios.
PHP API
=======
The API is considered "internal", however it might be necessary to provide
custom markup handling, add additional tags, attributes or values. The whole
process of sanitization is based on an "allow-list" - everything that is not
allowed, is automatically denied.
The following example is meant to give a brief overview of the behavior and
corresponding possibilities.
.. code-block:: php
<?php
use TYPO3\CMS\Core\Html\DefaultSanitizerBuilder;
use TYPO3\HtmlSanitizer\Behavior;
use TYPO3\HtmlSanitizer\Builder\BuilderInterface;
class MyCustomBuilder extends DefaultSanitizerBuilder implements BuilderInterface
{
public function createBehavior(): Behavior
{
// extends existing behavior, adds new tag
return parent::createBehavior()
->withName('my-custom')
->withTags(
(new Behavior\Tag('my-element', Behavior\Tag::ALLOW_CHILDREN))
->addAttrs(
(new Behavior\Attr('href'))->addValues(
new Behavior\RegExpAttrValue('#^(?:https?://|mailto:)#')
),
...$this->globalAttrs
)
);
}
}
As a result a new tag :html:`my-element` is which is allowed to
* have any safe global attribute (`id`, `class`, `data-*`, ...)
* have attribute `href`, in case corresponding value either starting with `http://`,
`http://` or `mailto:` - evaluated from the given regular expression
TypoScript
==========
stdWrap.htmlSanitize
--------------------
New :typoscript:`stdWrap` property :typoscript:`htmlSanitize` has been introduced
to control sanitization of markup, removing tags, attributes or values that have
not been allowed explicitly.
* `htmlSanitize = [boolean]` whether to invoke sanitization (enabled per default).
* `htmlSanitize.build = [string]` defines which specific builder (must be an
instance of :php:`\TYPO3\HtmlSanitizer\Builder\BuilderInterface`)
to be used for building a :php:`\TYPO3\HtmlSanitizer\Sanitizer`
instance using a particular :php:`\TYPO3\HtmlSanitizer\Behavior`.
This can either be a fully qualified class name or the name of a preset as
defined in :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['htmlSanitizer']` - per
default, :php:`\TYPO3\CMS\Core\Html\DefaultSanitizerBuilder` is used.
.. code-block:: typoscript
10 = TEXT
10 {
value = <div><img src="invalid.file" onerror="alert(1)"></div>
htmlSanitize = 1
// htmlSanitize.build = default
// htmlSanitize.build = TYPO3\CMS\Core\Html\DefaultSanitizerBuilder
}
stdWrap.parseFunc
-----------------
:typoscript:`stdWrap.htmlSanitize` is enabled per default when
:typoscript:`stdWrap.parseFunc` is invoked. This also includes Fluid
view-helper :html:`<f:format.html>`, since it invokes :php:`parseFunc`
using :typoscript:`lib.parseFunc_RTE` directly.
The following example shows how sanitization behavior - enabled per default -
can be disabled. This is not recommended, but occasionally might be necessary.
.. code-block:: typoscript
// either disable globally
lib.parseFunc.htmlSanitize = 0
lib.parseFunc_RTE.htmlSanitize = 0
// or disable individually per use-case
10 = TEXT
10 {
value = <div><img src="invalid.file" onerror="alert(1)"></div>
parseFunc =< lib.parseFunc_RTE
parseFunc.htmlSanitize = 0
}
Troubleshooting
---------------
Since any invocation of :typoscript:`stdWrap.parseFunc` triggers HTML
sanitization per default - except it is disabled explicitly - the following
example lead to lots of generated markup being sanitized - and was solved by
explicitly disabling it using :typoscript:`htmlSanitize = 0`.
.. code-block:: typoscript
10 = FLUIDTEMPLATE
10 {
templateRootPaths {
// ...
}
variables {
// ...
}
stdWrap.parseFunc {
// replace --- with soft-hyphen
short.--- = &shy;
// sanitization of ALL MARKUP is NOT DESIRED here
htmlSanitize = 0
}
}
HTML sanitization should be used for user-submitted input like rich-text
data - but not for the overall markup of a complete website.
Backend RTE configuration
=========================
Processing instructions for rich-text fields in the backend user interface
can be adjusted in a similar way, e.g. in :file:`Configuration/Processing.yaml`.
.. code-block:: yaml
processing:
allowTags:
# ...
HTMLparser_db:
# ...
htmlSanitize:
# use default builder as configured in
# $GLOBALS['TYPO3_CONF_VARS']['SYS']['htmlSanitizer']
build: default
# disable individually per use-case
# htmlSanitize: false
Sanitization for persisting data can be needs to be enabled globally using corresponding
feature flag :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.backend.htmlSanitizeRte']`.
Debugging & Logging
===================
In order to debug and log occurrences that have been modified during the sanitization
process, following configuration can be configured in corresponding :php:`LOG` section
of :file:`typo3conf/LocalConfiguration.php`.
.. code-block:: php
// ...
'LOG' => [
'TYPO3' => [
'HtmlSanitizer' => [
'writerConfiguration' => [
\TYPO3\CMS\Core\Log\LogLevel::DEBUG => [
'TYPO3\CMS\Core\Log\Writer\FileWriter' => [
'logFileInfix' => 'html',
],
],
],
],
],
],
// ...
Which produces log entries in e.g. :file:`typo3temp/var/log/typo3_html_[hash-value].log` like below
.. code-block:: text
Wed, 11 Aug 2021 09:03:08 +0200 [DEBUG] request="b62c11bcbd3d7"
component="TYPO3.HtmlSanitizer.Visitor.CommonVisitor":
Found invalid attribute a.href - {"behavior":"default","nodeName":"a","attrName":"href"}
Wed, 11 Aug 2021 09:03:08 +0200 [DEBUG] request="b62c11bcbd3d7"
component="TYPO3.HtmlSanitizer.Visitor.CommonVisitor":
Found invalid attribute div.onmouseover - {"behavior":"default","nodeName":"div","attrName":"onmouseover"}
Wed, 11 Aug 2021 09:03:08 +0200 [DEBUG] request="b62c11bcbd3d7"
component="TYPO3.HtmlSanitizer.Visitor.CommonVisitor":
Found unexpected tag script - {"behavior":"default","nodeName":"script"}
.. index:: Backend, Frontend, ext:core
@@ -0,0 +1,41 @@
.. include:: /Includes.rst.txt
.. _important-94492:
===========================================
Important: #94492 - Introduce SVG Sanitizer
===========================================
See :issue:`94492`
Description
===========
SVG sanitization behavior of extension `t3g/svg-sanitizer <https://packagist.org/packages/t3g/svg-sanitizer>`__
has been introduced into TYPO3 core. Actual processing is done by low-level sanitization package
`enshrined/svg-sanitize <https://packagist.org/packages/enshrined/svg-sanitize>`__ by Daryll Doyle.
Introduced aspects
------------------
* handle :php:`GeneralUtility::upload_copy_move` invocations
* handle FAL action events `file-add`, `file-replace`, `set-content`
* provide upgrade wizard, sanitizing all SVG files in storages that
are using :php:`\TYPO3\CMS\Core\Resource\Driver\LocalDriver`
Custom usage
------------
.. code-block:: php
$sanitizer = new \TYPO3\CMS\Core\Resource\Security\SvgSanitizer();
$sanitizer->sanitizeFile($sourcePath, $targetPath);
$svg = $sanitizer->sanitizeContent($svg);
Basically this change enforces following public service announcements
concerning SVG files, to enhance these security aspects per default:
* `TYPO3-PSA-2020-003: Mitigation of Cross-Site Scripting Vulnerabilities in File Upload Handling <https://typo3.org/security/advisory/typo3-psa-2020-003>`__
* `TYPO3-PSA-2019-010: Cross-Site Scripting Vulnerabilities in File Upload Handling <https://typo3.org/security/advisory/typo3-psa-2019-010>`__
.. index:: Backend, FAL, Frontend, ext:core
+43
View File
@@ -0,0 +1,43 @@
:template: changelogOverview.html
.. include:: /Includes.rst.txt
.. _changelog-9-5-x:
=============
9.5.x Changes
=============
**Table of contents**
.. contents::
:local:
:depth: 1
Features
========
.. toctree::
:maxdepth: 1
:titlesonly:
:glob:
Feature-*
Deprecation
===========
.. toctree::
:maxdepth: 1
:titlesonly:
:glob:
Deprecation-*
Important
=========
.. toctree::
:maxdepth: 1
:titlesonly:
:glob:
Important-*