Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
theme_system_modules_details($variables) calls SafeMarkup::set() which is meant to be for internal use only.
Proposed resolution
- Remove the call by refactoring the code.
- If refactoring is not possible, thoroughly document where the string is coming from and why it is safe, and why SafeMarkup::set() is required.
Remaining tasks
- Evaluate whether the string can be refactored to one of the formats outlined in this change record: https://www.drupal.org/node/2311123
- Identify whether there is existing automated test coverage for the sanitization of the string. If there is, list the test in the issue summary. If there isn't, add an automated test for it.
- If the string cannot be refactored, the SafeMarkup::set() usage needs to be thoroughly audited and documented.
Manual testing steps (for double escaping)
Do these steps both with HEAD and with the patch applied:
- Clean install of Drupal 8.
- Visit the modules list aka "Extend" (admin/modules)
- Compare the output above in HEAD and with the patch applied. Confirm that there is no double-escaping.
User interface changes
N/A
API changes
N/A
Comment | File | Size | Author |
---|---|---|---|
#38 | Extend___drupal_8_0_x.png | 158 KB | joelpittet |
#37 | interdiff.txt | 525 bytes | golddragon007 |
#37 | remove_or_document-2501737-37.patch | 2.06 KB | golddragon007 |
#34 | remove_or_document-2501737-34.patch | 2.04 KB | lauriii |
#24 | interdiff.txt | 1.12 KB | lauriii |
Comments
Comment #1
sclapp CreditAttribution: sclapp as a volunteer commentedwill approach by refactoring, slightly extraneous comment
Comment #2
sclapp CreditAttribution: sclapp as a volunteer commentedComment #3
sclapp CreditAttribution: sclapp as a volunteer commentedComment #6
star-szrMinor title tweak :)
Comment #7
joelpittetCouple of nitpicks but I think this is looking good thanks @sclapp
The format of the array is not in the format of our coding standards, will discuss IRL.
Array syntax should be the short syntax.
Comment #8
sclapp CreditAttribution: sclapp as a volunteer commentedChanged the syntax to short array format, in line with coding standards in the patch
Comment #10
joelpittetI think this should fix some of the fails... one sec I'll explain...
Comment #11
joelpittetThere was another SafeMarkup::set in that file.
As much as I love short syntax this line wasn't changed for the issue so the short syntax doesn't need to change.
These lines were accidentally deleted. Likely the reason for the failures.
There was a missing space between the , and the [. And all the words in keywords I put an underscore to separate the words.
This was also out of scope.
more of my favourite syntax that is out of scope.
Comment #12
akalata CreditAttribution: akalata as a volunteer commentedmanually tested #10; the HTML output is identical. (joelpiettet's comments in #11 apply to #8)
Comment #13
akalata CreditAttribution: akalata as a volunteer commentedComment #16
akalata CreditAttribution: akalata as a volunteer commentedManually tested this patch; the HTML output is identical.
Patch replaces SafeMarkup::set with SafeMarkup::format in 2 instances
- @id/@enable_id/@module_name are generated using module-specific values generated by system_rebuild_module_data(). I could not find specifically if/where ExtensionDiscovery::scan, InfoParser, etc sanitizes data pulled from the module's .info.yml file
- updating second line to short array syntax
- @description uses module-specific values from same source as above
It does not appear that content provided in the .info.yml file is appropriately sanitized. In some quick testing, adding
into a module description will run the script where the description is displayed (module list), and HTML tags are rendered for both description and name/title -- so I'm thinking this needs to be fixed before we can declare the content safe? Or are we just trusting module devs at this point?Comment #17
akalata CreditAttribution: akalata as a volunteer commentedComment #18
lauriiiSo the variables are being sanitized because they are using @placeholder format. We still need to investigate if its necessary to have the drupal_render in the theme_system_modules_details.
Comment #19
chx CreditAttribution: chx commented> Or are we just trusting module devs at this point?
Yes, we do, you are about to run their PHP code on your server and you are worried about them XSS'ing you?? I don't think this is a real problem. Also, it makes bad_judgement auto enabling itself possible :P
Comment #20
joelpittetSince safemarkup::format approach is poo-poo'd. Inline template is probably better and @lauriii is right no need for the drupal_render, especially with this approach.
I gave it a go, but could use a second pair of eyes.
Comment #21
lauriiiTested this manually and seems to work. The code is also good and we will have one less drupal_render call! How ever we still need test coverage for this.
Comment #22
cilefen CreditAttribution: cilefen commentedIs the test needed for an XSS in the module description? That is what I did here. Is is not escaped.
Comment #24
lauriiiThis should fix the tests
Comment #25
dawehnerIsn't this case similar to the local task/menu links issue? So should the description here actually return a Translation Wrapper?
This doesn't protected against XSS, but to be honest a module author can produce an XSS in a different way SO easily
Comment #26
lauriiiI agree that there is too many ways module author can produce a XSS or even worse things to happen so maybe it doesn't make any sense to test this even though it would be nice. So lets remove the test and the SafeMarkup::escape().
Comment #27
YesCT CreditAttribution: YesCT commentedI'm not getting why "This doesn't protected against XSS,"
the patch in #24 looks to be escaping html from the description and has a test to prove it is.
#24 looks good to me...
Comment #28
xjmComment #29
xjmSo this is interesting.
I've temporarily unpublished this issue because the issue also exists in D7. @alexpott pointed out that one difference between this and other exploits a module author could introduce is that it can be executed without even installing the module; it just needs to be on the file system. That probably isn't a reason to consider this a sec issue and it is probably security hardening at most. But we should confirm this first with the sec team. @alexpott said he'd do so.
There is a use case for putting HTML in a module description I think, so XSS filtering over escaping would be preferable if we do decide it needs to be sanitized. Can someone manually test safe HTML in a module description, and if that is currently supported, add test coverage for it as well?
Also, in either case, we need to document what is allowed for module descriptions and whether or not it's expected to be safe.
Also, @alexpott pointed out that doing the escaping inside the translation breaks the translation, so the filtering or escaping should be done on the result of the t() call instead.
Comment #30
xjmtheme_system_modules_details()
could also potentially be converted to a template straight up, but that is likely a lot of work. It would be good to review it.Comment #31
mlhess CreditAttribution: mlhess commentedThe security issue is known and can be public.
Comment #32
pwolanin CreditAttribution: pwolanin as a volunteer and at Acquia commentedalso: #2527544: Module list page is not XSS safe
I would worry more (especially for D7) about a module that just buried a PHP shell among its files.
Comment #33
alexpottSo I think this issue should drop trying to make the description safe and leave that to #2527544: Module list page is not XSS safe. It should just focus on Remove or document SafeMarkup::set in theme_system_modules_details()
Comment #34
lauriiiThis is a rerolled version of #20 with extra space removed from the inline template.
Comment #35
star-szrHere is the related conversion issue.
Comment #36
joelpittetThis looks really close, thanks for the re-roll.
missing the CSS class "module-description".
Comment #37
golddragon007 CreditAttribution: golddragon007 at Brainsum commentedI've added that missing class name.
Comment #38
joelpittetThank you @golddragon007. I did a markup comparsion to make sure things aren't missing. Looks good thank you!
Comment #39
alexpottLate rendering++
Committed 8402939 and pushed to 8.0.x. Thanks!