Problem/Motivation

If a Tour tip label includes HTML tags or characters that will be converted to HTML entities by Html::escape() (e.g. ' to &#039;), those will appear double-escaped in the resulting Tour tip. For example, the label "What''s New with text in <strong>bold</strong>" would get output as this:

What&#039;s New with text in &lt;strong&gt;bold&lt;/strong&gt;

Screenshot showing double-escaped text

Steps to reproduce

1. Create a Tour with a tip with a label with text that will be escaped by Html::escape(). This YAML would work ( tour.tour_.test-admin.yml, attached):

langcode: en
status: true
dependencies:
  module:
    - system
id: test-admin
label: 'Admin page'
module: system
routes:
  -
    route_name: system.admin
tips:
  test-admin-main:
    id: test-admin-main
    plugin: text
    label: 'What''s New with text in <strong>bold</strong>'
    weight: 1
    attributes:
      class: no-nub
    body: 'This is the admin page of the Drupal site.'

2. Start Tour.
3. See tip with double-escaped text.

Proposed resolution

This is a caused by code in core/modules/tour/src/TourViewBuilder.php that calls Html::escape():

$output = [
  'body' => $body,
  'title' => Html::escape($tip->getLabel()),
];

This text does not need to be escaped here because it's already being done somewhere else. If we remove the call to Html::escape(), the resulting label will have the text properly escaped (once):

What's New with text in <strong>bold</strong>

screenshot showing correct text

Remaining tasks

1. Patch code to remove call to Html::escape().
2. Write test (is that needed?).
3. Commit change.

User interface changes

before

before

after

after

CommentFileSizeAuthor
#43 3255895-nr-bot.txt98 bytesneeds-review-queue-bot
#42 3255895-42-9.5-backport.patch1.6 KBmurilohp
#39 Screen Shot 2023-02-13 at 8.16.53 PM.png67.41 KBsmustgrave
#39 Screen Shot 2023-02-13 at 8.16.53 PM.png67.41 KBsmustgrave
#36 3255895-36.tour-double-escaped-html.patch1.58 KBjrb
#34 After.png95.6 KBameymudras
#34 Before.png108.31 KBameymudras
#32 3255895-32.tour-double-escaped-html.patch1.6 KBjrb
#31 3255895-31.tour-double-escaped-html.patch1.6 KBjrb
#29 error-in-comment-line.png25.96 KBanoopsingh92
#28 3255895-HTML-entities.patch1.63 KBharshitthakore
#27 3255895-HTML-entities-in-Tour-tip.patch1.71 KBanoopsingh92
#20 3255895-20.patch1.57 KBsandeepsingh199
#18 3255895_10.1.x.patch1.58 KBshubham chandra
#16 3255895after patch.png18.69 KBaarti zikre
#16 3255895_10.x.patch1.57 KBaarti zikre
#16 3255895_9.5.x.patch1.55 KBaarti zikre
#13 3255895-5-tour-double-escaped-html-13.patch1.58 KBkarishmaamin
#13 3255895-test-only-13.patch1002 byteskarishmaamin
#8 after_patch.png111.39 KBsmustgrave
#8 before_patch.png119.82 KBsmustgrave
#5 interdiff_2-5.txt874 bytesmurilohp
#5 3255895-5-tour-double-escaped-html.patch1.6 KBmurilohp
#5 3255895-test-only.patch1002 bytesmurilohp
#3 Screenshot 2021-12-25 at 8.40.17 PM.png111.13 KBgauravvvv
#3 Screenshot 2021-12-25 at 8.36.32 PM.png124.39 KBgauravvvv
#2 3255895-2.tour-double-escaped-html.patch629 bytesjrb
tour.tour_.test-admin.yml428 bytesjrb
Screenshot-20211223-19.31.55.png13.7 KBjrb
Screenshot-20211223-19.17.04.png17.35 KBjrb

Issue fork drupal-3255895

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jrb created an issue. See original summary.

jrb’s picture

Status: Active » Needs review
StatusFileSize
new629 bytes

Attached patch just removes the call to Html::escape(). Resulting label is escaped correctly.

gauravvvv’s picture

HTML entities in Tour tip labels get double-escaped fixed, Adding before and after patch screenshot for reference.
Before Patch

After Patch

Can be move to RTBC.

murilohp’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

I think it's a good catch! Thanks!!

The solution seens fine to me, but since it's a bug, I think it's important to have a test to cover this scenario.

Adding the tag and moving back to NW.

murilohp’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new1002 bytes
new1.6 KB
new874 bytes

Hey! I reviewed the tests and update them to validate the HTML entities scenarios, I'm uploading two new patchs, the first one is the test-only patch which should fail, the second is the new patch.

Moving back to needs review.

The last submitted patch, 5: 3255895-test-only.patch, failed testing. View results

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new119.82 KB
new111.39 KB

Verified the issue exists
Verified the patch fixed the issue.

Attaching screenshots to show.

The last submitted patch, 5: 3255895-test-only.patch, failed testing. View results

The last submitted patch, 5: 3255895-test-only.patch, failed testing. View results

The last submitted patch, 5: 3255895-test-only.patch, failed testing. View results

catch’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

Needs a re-roll for 10.x

karishmaamin’s picture

Status: Needs work » Needs review
StatusFileSize
new1002 bytes
new1.58 KB

Re-rolled patch against 10.0.x. Please review

aarti zikre’s picture

Version: 9.4.x-dev » 10.0.x-dev
Assigned: Unassigned » aarti zikre

reviewing this

The last submitted patch, 13: 3255895-test-only-13.patch, failed testing. View results

aarti zikre’s picture

StatusFileSize
new1.55 KB
new1.57 KB
new18.69 KB

changes in patch as it shows fail.
applied new patch on Drupal 10:

Reviewed and verified. looks good.

Testing steps:

* Install new drupal version.
* go to /admin/config/development/configuration/single/import.
* import given yml file.
* apply patch.
* start tour.

Testing result:

Output is : What's New with text in bold

This is the admin page of the Drupal site.

After patch
2022-08-01/3255895after patch.png

Please review this new patch for 9.5 and 10

aarti zikre’s picture

Assigned: aarti zikre » Unassigned
shubham chandra’s picture

StatusFileSize
new1.58 KB

Applied patch against #16 in Drupal 10.1.x

Status: Needs review » Needs work

The last submitted patch, 18: 3255895_10.1.x.patch, failed testing. View results

sandeepsingh199’s picture

StatusFileSize
new1.57 KB

Re-rolling patch #16 against 10.1.x. Kindly check & validate

sandeepsingh199’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 20: 3255895-20.patch, failed testing. View results

smustgrave’s picture

Version: 10.0.x-dev » 10.1.x-dev
Status: Needs work » Needs review
Issue tags: -Needs reroll +Bug Smash Initiative

#16 runs fine on 10.1 so the patches in #18 and 20 were not needed it appears.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Verified #16 also. Following the steps there and the steps in the IS.

quietone’s picture

The latest patch is failing tests and the last test run was in October. For some reason the patch is not being automatically retested. I will start a test now.

anoopsingh92 made their first commit to this issue’s fork.

anoopsingh92’s picture

StatusFileSize
new1.71 KB

Please review this patch.

harshitthakore’s picture

StatusFileSize
new1.63 KB
anoopsingh92’s picture

StatusFileSize
new25.96 KB

Thanks @harshitthakore, for removing the commented lines. I forgot to add space before the comment text.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 28: 3255895-HTML-entities.patch, failed testing. View results

jrb’s picture

Status: Needs work » Needs review
StatusFileSize
new1.6 KB

The patch in #20 had a good test, but the patches starting with #27 had incorrect labels in the test. Attached patch reverts the test back to what it was back in #20.

jrb’s picture

StatusFileSize
new1.6 KB

White space in previous patch was messed up. Trying again...

gauravvvv’s picture

ameymudras’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new108.31 KB
new95.6 KB

Tested #32 on Drupal 10.1.x and following are my findings:

1. Issue summary is clear and steps to reproduce have been provided
2. Was able to reproduce the issue on Drupal 10.1
3. The patch applies cleanly and fixes the issue. Provided screenshots for reference as there was a code change since last manual test
4. No issues found in the code review
5. Don't think supporting test is required here

Marking as RTBC

xjm’s picture

Status: Reviewed & tested by the community » Needs work
--- a/core/modules/tour/src/TourViewBuilder.php
+++ b/core/modules/tour/src/TourViewBuilder.php

@@ -43,7 +43,7 @@ public function viewMultiple(array $entities = [], $view_mode = 'full', $langcod
-          'title' => Html::escape($tip->getLabel()),
+          'title' => Html::decodeEntities($tip->getLabel()),

This is dangerous. We are switching from something intended to sanitize the tip label to something that effectively un-sanitizes any previous sanitization. This could allow XSS to be injected in the tip label.

We should either consider using Markup objects/render arrays properly here, or use Xss::filter().

In order to make a decision of which of those options to use, we need to see where $tip->label is coming from. How is it defined? Is it already a Markup object, or is it a plain string? Etc. Just saying that "it is already escaped somewhere" without looking into where and how is insecure coding.

jrb’s picture

Status: Needs work » Needs review
StatusFileSize
new1.58 KB

Ugh. You're right, @xjm. The patches stating in #27 not only had incorrect labels in the test, but also incorrectly added the Html::decodeEntities(). The attached patch here just removes the original Html::escape() only per the earlier patches:

--- a/core/modules/tour/src/TourViewBuilder.php
+++ b/core/modules/tour/src/TourViewBuilder.php

@@ -43,7 +43,7 @@ public function viewMultiple(array $entities = [], $view_mode = 'full', $langcod
-          'title' => Html::escape($tip->getLabel()),
+          'title' => $tip->getLabel(),

This should be secure because the code in core/modules/tour/js/tour.es6.js runs Drupal.checkPlain() on the title it gets:

const tourItemOptions = {
  title: tourStepConfig.title
    ? Drupal.checkPlain(tourStepConfig.title)
    : null,
  text: () => Drupal.theme('tourItemContent', tourStepConfig),
  attachTo: tourStepConfig.attachTo,
  buttons: [Drupal.tour.nextButton(shepherdTour, tourStepConfig)],
  classes: tourStepConfig.classes,
  index,
};

Status: Needs review » Needs work

The last submitted patch, 36: 3255895-36.tour-double-escaped-html.patch, failed testing. View results

jrb’s picture

Status: Needs work » Needs review

@xjm, would you please take a look again? The tests passed now (they had previously failed for reasons unrelated to this patch).

smustgrave’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs Review Queue Initiative
StatusFileSize
new67.41 KB
new67.41 KB

Retested #36 following the issue summary.

Posted before/after screenshots to issue summary.

#35 looks to have been addressed.

  • lauriii committed 18c67bff on 10.1.x
    Issue #3255895 by jrb, murilohp, harshitthakore, xjm: HTML entities in...
lauriii’s picture

Confirmed that the title is not being used anywhere else than what was pointed out in #36.

Committed 18c67bf and pushed to 10.1.x. Thanks!

Leaving open for 10.0.x and 9.5.x backport.

murilohp’s picture

StatusFileSize
new1.6 KB

Hey @lauriii, here's a patch for 9.5, #36 is applying corrcetly on 10.0.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new98 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

mrinalini9’s picture

Status: Needs work » Needs review

Hi,

It seems that the changes in patch #42 are already present in 10.1.x branch. So, reroll is not needed for 10.1.x.

Thanks & Regards,
Mrinalini

lauriii’s picture

Version: 10.1.x-dev » 10.0.x-dev
Status: Needs review » Reviewed & tested by the community

#42 is not supposed to work with 10.1.x since it's only for 9.5.x. Moving back to RTBC.

  • lauriii committed bfecafcf on 10.0.x
    Issue #3255895 by jrb, murilohp, harshitthakore, xjm: HTML entities in...

  • lauriii committed ae16bcd7 on 9.5.x
    Issue #3255895 by jrb, murilohp, harshitthakore, lauriii, xjm: HTML...
lauriii’s picture

Version: 10.0.x-dev » 9.5.x-dev
Status: Reviewed & tested by the community » Fixed

Cherry-picked to 10.0.x and committed #42 to 9.5.x. Thank you!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

kristen pol’s picture

Was reviewing this issue. I'm not understanding why smustgrave and ameymudras and possibly others were not given issue credit as they had genuine contributions IMO but this issue is closed so maybe it won't be changed.

lauriii’s picture

I didn't credit @smustgrave, @ameymudras or anyone else for posting screenshots to this issue since this issue did not benefit from screenshots besides the one that was part of the original issue summary. What it needed was code review. What comes to crediting code review, we only give credit for substantial code reviews. In the case of this issue, it could have been explaining why the change that is being proposed in \Drupal\tour\TourViewBuilder is fine.

kristen pol’s picture

Thank you for the explanation. I’ll need to figure out how to better find issues to work on and then help my coworkers do the same. I need to better understand what actually requires testing given these issues I’ve been reviewing seem to not need it.