From f66a20d382dad4622521192a743561e9b796ca5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Chris=20M=C3=BCller?= <typo3@krue.ml>
Date: Mon, 4 May 2020 13:14:26 +0200
Subject: [PATCH] [TASK] Add rel="noreferrer" to external links of widgets

Clicking on external links (with target="_blank") in RSS widgets and buttons
of Dashboard widgets can leak the referrer of the linked page. This is mostly
not wanted because it reveals the URL of the TYPO3 backend. Additionally, the
other page can access the "window.opener" property, which exposes security
issues. Also if the other page is running a lot of JavaScript, the performance
of the TYPO3 backend may also suffer, because the other page may run on the
same process as the TYPO3 backend.

To mitigate this behaviour rel="noreferrer" is added to external links
in the according widgets.

"noreferrer" also implies the "noopener" behaviour, so this is sufficient.

See also:
- https://html.spec.whatwg.org/multipage/links.html#link-type-noreferrer
- https://developers.google.com/web/tools/lighthouse/audits/noopener

Resolves: #91290
Releases: master
Change-Id: Ie53b543e39bc716a5437d9a7364691de3ec7346f
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/64401
Reviewed-by: Josef Glatz <josefglatz@gmail.com>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
Reviewed-by: Richard Haeser <richard@maxserv.com>
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Josef Glatz <josefglatz@gmail.com>
Tested-by: Oliver Bartsch <bo@cedev.de>
Tested-by: Richard Haeser <richard@maxserv.com>
---
 .../Resources/Private/Partials/Widget/Button.html         | 5 +++++
 .../Resources/Private/Templates/Widget/ChartWidget.html   | 6 +-----
 .../Resources/Private/Templates/Widget/CtaWidget.html     | 6 ++----
 .../Resources/Private/Templates/Widget/ListWidget.html    | 6 ++----
 .../Resources/Private/Templates/Widget/RssWidget.html     | 8 +++-----
 5 files changed, 13 insertions(+), 18 deletions(-)
 create mode 100644 typo3/sysext/dashboard/Resources/Private/Partials/Widget/Button.html

diff --git a/typo3/sysext/dashboard/Resources/Private/Partials/Widget/Button.html b/typo3/sysext/dashboard/Resources/Private/Partials/Widget/Button.html
new file mode 100644
index 000000000000..7de7f52b7a39
--- /dev/null
+++ b/typo3/sysext/dashboard/Resources/Private/Partials/Widget/Button.html
@@ -0,0 +1,5 @@
+<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
+<f:if condition="{button}">
+        <a href="{button.link}" class="widget-cta"{f:if(condition: '{button.target}', then: ' target="{button.target}"')}{f:if(condition: '{button.target} == "_blank"', then: ' rel="noreferrer"')}>{f:translate(id: button.title, default: button.title)}</a>
+</f:if>
+</html>
diff --git a/typo3/sysext/dashboard/Resources/Private/Templates/Widget/ChartWidget.html b/typo3/sysext/dashboard/Resources/Private/Templates/Widget/ChartWidget.html
index e446cdfe702a..0bbe2baf0034 100644
--- a/typo3/sysext/dashboard/Resources/Private/Templates/Widget/ChartWidget.html
+++ b/typo3/sysext/dashboard/Resources/Private/Templates/Widget/ChartWidget.html
@@ -8,10 +8,6 @@
 
 </f:section>
 <f:section name="footer">
-
-    <f:if condition="{button}">
-        <a href="{button.link}" target="{button.target}" class="widget-cta">{f:translate(id: button.title, default: button.title)}</a>
-    </f:if>
-
+    <f:render partial="Widget/Button" arguments="{button: button}"/>
 </f:section>
 </html>
diff --git a/typo3/sysext/dashboard/Resources/Private/Templates/Widget/CtaWidget.html b/typo3/sysext/dashboard/Resources/Private/Templates/Widget/CtaWidget.html
index 226397f55559..2b3e42d02f59 100644
--- a/typo3/sysext/dashboard/Resources/Private/Templates/Widget/CtaWidget.html
+++ b/typo3/sysext/dashboard/Resources/Private/Templates/Widget/CtaWidget.html
@@ -1,4 +1,4 @@
-<html 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">
+<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
 <f:layout name="Widget/Widget"/>
 <f:section name="main">
 
@@ -8,8 +8,6 @@
 
 </f:section>
 <f:section name="footer">
-    <f:if condition="{button}">
-        <a href="{button.link}" target="{button.target}" class="widget-cta">{f:translate(id: button.title, default: button.title)}</a>
-    </f:if>
+    <f:render partial="Widget/Button" arguments="{button: button}"/>
 </f:section>
 </html>
diff --git a/typo3/sysext/dashboard/Resources/Private/Templates/Widget/ListWidget.html b/typo3/sysext/dashboard/Resources/Private/Templates/Widget/ListWidget.html
index d0d4cdf9fc81..a0c809d38d91 100644
--- a/typo3/sysext/dashboard/Resources/Private/Templates/Widget/ListWidget.html
+++ b/typo3/sysext/dashboard/Resources/Private/Templates/Widget/ListWidget.html
@@ -1,4 +1,4 @@
-<html 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">
+<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
 <f:layout name="Widget/Widget" />
 <f:section name="main">
 
@@ -12,8 +12,6 @@
 
 </f:section>
 <f:section name="footer">
-    <f:if condition="{button}">
-        <a href="{button.link}" target="{button.target}" class="widget-cta">{f:translate(id: button.title, default: button.title)}</a>
-    </f:if>
+    <f:render partial="Widget/Button" arguments="{button: button}"/>
 </f:section>
 </html>
diff --git a/typo3/sysext/dashboard/Resources/Private/Templates/Widget/RssWidget.html b/typo3/sysext/dashboard/Resources/Private/Templates/Widget/RssWidget.html
index 0e3e54596607..3875ec5b7343 100644
--- a/typo3/sysext/dashboard/Resources/Private/Templates/Widget/RssWidget.html
+++ b/typo3/sysext/dashboard/Resources/Private/Templates/Widget/RssWidget.html
@@ -1,4 +1,4 @@
-<html 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">
+<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
 <f:layout name="Widget/Widget" />
 <f:section name="main">
 
@@ -7,7 +7,7 @@
             <f:for each="{items}" as="item">
                 <tr>
                     <td>
-                        <f:link.external uri="{item.link}" target="_blank"><strong>{item.title}</strong></f:link.external>
+                        <f:link.external uri="{item.link}" target="_blank" rel="noreferrer"><strong>{item.title}</strong></f:link.external>
                         <small><time datetime="{item.pubDate -> f:format.date(format: '%Y-%m-%d')}">{item.pubDate -> f:format.date()}</time></small>
                         <p>{item.description -> f:format.crop(maxCharacters: 180)}</p>
                     </td>
@@ -18,8 +18,6 @@
 
 </f:section>
 <f:section name="footer">
-    <f:if condition="{button}">
-        <a href="{button.link}" target="{button.target}" class="widget-cta">{f:translate(id: button.title, default: button.title)}</a>
-    </f:if>
+    <f:render partial="Widget/Button" arguments="{button: button}"/>
 </f:section>
 </html>
-- 
GitLab