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 '), 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's New with text in <strong>bold</strong>

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>

Remaining tasks
1. Patch code to remove call to Html::escape().
2. Write test (is that needed?).
3. Commit change.
User interface changes
before

after

| Comment | File | Size | Author |
|---|---|---|---|
| #43 | 3255895-nr-bot.txt | 98 bytes | needs-review-queue-bot |
| #42 | 3255895-42-9.5-backport.patch | 1.6 KB | murilohp |
| #39 | Screen Shot 2023-02-13 at 8.16.53 PM.png | 67.41 KB | smustgrave |
| #39 | Screen Shot 2023-02-13 at 8.16.53 PM.png | 67.41 KB | smustgrave |
| #36 | 3255895-36.tour-double-escaped-html.patch | 1.58 KB | jrb |
Issue fork drupal-3255895
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
Comment #2
jrbAttached patch just removes the call to
Html::escape(). Resulting label is escaped correctly.Comment #3
gauravvvv commentedHTML 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.
Comment #4
murilohp commentedI 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.
Comment #5
murilohp commentedHey! 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.
Comment #8
smustgrave commentedVerified the issue exists
Verified the patch fixed the issue.
Attaching screenshots to show.
Comment #12
catchNeeds a re-roll for 10.x
Comment #13
karishmaamin commentedRe-rolled patch against 10.0.x. Please review
Comment #14
aarti zikre commentedreviewing this
Comment #16
aarti zikre commentedchanges 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

Please review this new patch for 9.5 and 10
Comment #17
aarti zikre commentedComment #18
shubham chandra commentedApplied patch against #16 in Drupal 10.1.x
Comment #20
sandeepsingh199 commentedRe-rolling patch #16 against 10.1.x. Kindly check & validate
Comment #21
sandeepsingh199 commentedComment #23
smustgrave commented#16 runs fine on 10.1 so the patches in #18 and 20 were not needed it appears.
Comment #24
smustgrave commentedVerified #16 also. Following the steps there and the steps in the IS.
Comment #25
quietone commentedThe 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.
Comment #27
anoopsingh92Please review this patch.
Comment #28
harshitthakoreComment #29
anoopsingh92Thanks @harshitthakore, for removing the commented lines. I forgot to add space before the comment text.
Comment #31
jrbThe 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.
Comment #32
jrbWhite space in previous patch was messed up. Trying again...
Comment #33
gauravvvv commentedComment #34
ameymudras commentedTested #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
Comment #35
xjmThis 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->labelis 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.Comment #36
jrbUgh. 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 originalHtml::escape()only per the earlier patches:This should be secure because the code in
core/modules/tour/js/tour.es6.jsrunsDrupal.checkPlain()on the title it gets:Comment #38
jrb@xjm, would you please take a look again? The tests passed now (they had previously failed for reasons unrelated to this patch).
Comment #39
smustgrave commentedRetested #36 following the issue summary.
Posted before/after screenshots to issue summary.
#35 looks to have been addressed.
Comment #41
lauriiiConfirmed 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.
Comment #42
murilohp commentedHey @lauriii, here's a patch for 9.5, #36 is applying corrcetly on 10.0.
Comment #43
needs-review-queue-bot commentedThe 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.
Comment #44
mrinalini9 commentedHi,
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
Comment #45
lauriii#42 is not supposed to work with 10.1.x since it's only for 9.5.x. Moving back to RTBC.
Comment #48
lauriiiCherry-picked to 10.0.x and committed #42 to 9.5.x. Thank you!
Comment #50
kristen polWas 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.
Comment #51
lauriiiI 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\TourViewBuilderis fine.Comment #52
kristen polThank 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.