Disclaimer: I'm not sure in which component I have to put this issue. Feel free to move it.
Problem/Motivation
The locale_string_is_safe
function is used by the Locale module to ensure that translations are safe before saving them in the database. It does so by comparing an Xss::filter-ed version to the original version so nothing serious can happen. If that function fails, the string become totally untranslatable unless you want to manually put your translation into the database.
In some cases (see the parent issue), when a href attribute (or an attribute supposed to include an URL) starts with a token, this one is wrongly and partially stripped out so the comparison fails and so the string becomes untranslatable.
There is a simple example :
\Drupal\Component\Utility\Xss::filter('Return to the <a href="[site:url]">frontpage</a>');
// 'Return to the <a href="url]">frontpage</a>'
This issue affects two strings in core (Locale module's tour configuration) but it could affect a lot of contrib modules (and it's probably already the case). The parent issue is about to bypass this particular problem in the translation context but it would be safer and stronger to directly fix Xss::filter.
Proposed resolution
Fix Xss::filter to avoid it stripping these tokens.
Remaining tasks
Task | Novice task? | Contributor instructions | Complete? |
---|---|---|---|
Create a patch | Instructions | ||
Add automated tests | Instructions |
User interface changes
None
API changes
None
Comments
Comment #1
ericmulder1980 CreditAttribution: ericmulder1980 commentedI will work on this issue today during the Amsterdam Core sprint.
Comment #2
ericmulder1980 CreditAttribution: ericmulder1980 commentedSmall update on how to reproduce this issue.
1. Install Drupal core
2. Enable Interface Translation, Tour and Language modules
3. Add an extra language to your site (admin/config/regional/language)
4. Go to Interface translation interface (admin/config/regional/translate)
5. Search for the sring "This page allows you to".
6. Copy the matched source string into the translation text field without altering it.
7. Hit the "save translation" button
You will now receive an error message stating "The submitted string contains disallowed HTML".
Comment #3
ericmulder1980 CreditAttribution: ericmulder1980 commentedIssue seems to be in method Xss::split(). String is valid when entering this method and messed up when returning the value.
I will try to remain active in solving this issue but feel free to "hijack" this issue.
Comment #4
ericmulder1980 CreditAttribution: ericmulder1980 commentedComment #5
chx CreditAttribution: chx commentedI would subclass
Xss
and change thecase 2
inattributes
to accept a well formatted token. ChangingXss
worries me a bit but we need more security team on this issue.Comment #6
penyaskitoI think this is the right tag to get more exposure to the secteam.
Comment #7
dawehnerOne thing i'm wondering is: Why would you ever use
Xss::filter
on something which is not meant as HTML yet?Comment #9
stefan.r CreditAttribution: stefan.r commentedI just ran into this issue while translating a string with a token in it in the translation interface.
Regarding #7, just an example... locale_string_is_safe() is run during validation when submitting a translated string, which does decode_entities($string) == decode_entities(filter_xss($string)), which seems correct to me.
So the issue is that a string like
<a href="[site:url]">Home</a>
erroneously gets filtered into<a href="url]">Home</a>
Comment #10
stefan.r CreditAttribution: stefan.r commentedComment #12
Eric_A CreditAttribution: Eric_A commentedI changed the PHP code markup in the issue summary so it now actually shows the issue. Also, AFAIK there's no workaround for this, major bug to me.
Question: is this a regression introduced in D7 by #2371861: Strings including tokens in href or src attributes cannot be translated due to safeness check incompatibilities? Guess not... Then how long does this terrible bug exists?
Comment #13
Eric_A CreditAttribution: Eric_A commentedI needed a fix now for
_wysiwyg_filter_xss_attributes()
for the same bug so I posted a patch in wysiwyg_filter.The code should be the same the same though, apart from it being a D7 patch. Not sure if and when I'm going to find the time to port to core D8.
Here is the wysiwyg_filter patch:
Comment #14
darrenwh CreditAttribution: darrenwh as a volunteer and at Investis Digital commentedHi,
Looking at the function filter in Xss.php I've isolated the line that does this change to line 94:
Adding a colon to the expression like so :
returns a string like
<a href="[site:url]">frontpage</a>
So I think that inside the first part of the regex we need to add more a specific pattern for a tag to allow it to be excluded from filtering?
Comment #15
cilefen CreditAttribution: cilefen as a volunteer commentedComment #17
catchComment #18
cilefen CreditAttribution: cilefen as a volunteer commentedComment #19
catchMarking duplicate of #2635632: Drupal XSS filtering cuts valid attributes, make it configurable / use a blacklist (which I've retitled).
Comment #20
markusd1984 CreditAttribution: markusd1984 commentedBig thanks @Eric_A for #13, saved my day! Surprised there aren't any modules yet to implement a filter to work around this.
Only found this useful posts Allow tokens for url of the Link field and custom filter CKEditor mangles tokens in URLs, due to bug in Xss::attributes() that I couldn't test yet and thinks if not for drupal 7?!?