...which makes it almost impossible to implement translatable blocks.
People, blocks without divs and imgs are useless!
Yes, I've read explanation for this in locale.inc (lines 837-839), but IMHO this is simply not correct.
abstract from locale.inc:
* The allowed tag list is like filter_xss_admin(), but omitting div and img as
* not needed for translation and likely to cause layout issues (div) or a
* possible attack vector (img).
*/
function locale_string_is_safe($string) {
return decode_entities($string) == decode_entities(filter_xss($string, array('a', 'abbr', 'acronym', 'address', 'b', 'bdo', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'ins', 'kbd', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var')));
}
| Comment | File | Size | Author |
|---|---|---|---|
| #30 | 352121-locale-string-safe-non-default-backport.patch | 1.44 KB | mr.baileys |
| #21 | 352121-locale-string-safe-non-default.patch | 4.93 KB | damien tournoud |
| #19 | issue-352121.patch | 1.59 KB | lilou |
| #17 | locale.inc_.patch | 1.27 KB | valthebald |
| #15 | locale.inc_.patch | 1.29 KB | valthebald |
Comments
Comment #1
valthebaldComment #2
gábor hojtsyGot a tip at http://drupal.org/node/276111 that it caused problems.
Allowing img and div in translations would open all Drupal sites to XSS attacks once we put the online translation server in place with automated distribution of translations. People seem to want to have more automated distribution for translations, but we could not do it without having proper protection against attacks on your site.
We might be able to use the textgroup to assume non-default textgroups strings as safe (given we treat them as user input) regardless of their content to let i18nstrings module to work. The non-default textgroups are used to store stuff which will be displayed through the filter system or other mechanisms to escape content (at least they are assumed to be used as such).
Comment #3
gábor hojtsyRetitled.
Comment #4
valthebaldI'm not sure how translation server is invoked to import translations.
Does it call locale_translate_edit_form_validate()? 'Cause if not, and locale_translate_edit_form_validate is called in case of user input,
then it's possible to patch locale.inc somewhat like (attached as patch as well)
--- includes/locale.inc
+++ includes/locale.inc
@@ -847,10 +847,7 @@
*/
function locale_translate_edit_form_validate($form, &$form_state) {
foreach ($form_state['values']['translations'] as $key => $value) {
- if (!locale_string_is_safe($value)) {
- form_set_error('translations', t('The submitted string contains disallowed HTML: %string', array('%string' => $value)));
- watchdog('locale', 'Attempted submission of a translation string with disallowed HTML: %string', array('%string' => $value), WATCHDOG_WARNING);
- }
+ $form_state['values']['translations'][$key] = check_plain($value);
}
}
Comment #5
gábor hojtsyGrm, I am just saying that if the form state says we deal with a non-default textgroup, we should skip this security check. Your patch always removes this check which is not right.
Comment #6
valthebaldOk, didn't understand your initial comment.
Here's updated version (is it what you meant?):
Index: includes/locale.inc
===================================================================
--- includes/locale.inc
+++ includes/locale.inc
@@ -846,8 +846,9 @@
* Validate string editing form submissions.
*/
function locale_translate_edit_form_validate($form, &$form_state) {
+ $safe_check_needed = $form_state['values']['textgroup']=='default'; // locale string check is needed for default textgroup only
foreach ($form_state['values']['translations'] as $key => $value) {
- if (!locale_string_is_safe($value)) {
+ if ($safe_check_needed && !locale_string_is_safe($value)) {
form_set_error('translations', t('The submitted string contains disallowed HTML: %string', array('%string' => $value)));
watchdog('locale', 'Attempted submission of a translation string with disallowed HTML: %string', array('%string' => $value), WATCHDOG_WARNING);
}
Comment #7
gábor hojtsyYes, except some coding style changes. We'd need to have the comment on the line before in sentence format (capitalized at the start, dot at the end). Also, the same needs to be done with .po files imported with the textgroup specified. That should cover the cases we have in core IMHO.
Comment #8
valthebaldthe same needs to be done with .po files imported with the textgroup specified - what do you mean?
Comment #9
gábor hojtsyWhen .po files are imported on the locale interface, you can choose a textgroup. .po files not imported for the default textgroup should also omit this check to be in line with what we do here.
Comment #10
valthebaldI still don't get the point why add some global check for all locale strings, when in fact, we need only to check input from translation server?
Maybe it's better to check input from translation server, and that's it? I'm not so aware of drupal core internals to quickly find callback which handles such input, the only thing I found is i10n_server/i10n_client pair. If I'm right, then it's no need to place check in locale.inc at all, but place it in i10n_client.
Comment #11
valthebaldI still don't get the point why add some global check for all locale strings, when in fact, we need only to check input from translation server?
Maybe it's better to check input from translation server, and that's it? I'm not so aware of drupal core internals to quickly find callback which handles such input, the only thing I found is i10n_server/i10n_client pair. If I'm right, then it's no need to place check in locale.inc at all, but place it in i10n_client.
Comment #12
gábor hojtsy@valthebald: The l10n_client currently does not pull translations from a server, and the reason was exactly this problem (of using unfiltered strings) not being fixed. Now that we are filtering those, we can finally implement it. However, the l10n_server's currently export .po files for import in Drupal. Now the .po import always does this check. But you can export and do your block translations outside of Drupal as well with the same .po mechanism. So there we should also have a textgroup dependent check.
Comment #13
valthebaldSorry for delay - you know, all these holidays and damn fanatics on our South...
Anyway, attached patch added check on strings import (for default textgroup only), as well as form submit check
Comment #14
damien tournoud commentedThe patch looks good. Some (minor) coding style issues:
We (virtually) always put comments on their own line. Plus comments should be proper sentences (beginning with an uppercase letter, ending with a period).
We don't use C style comments inline. Please transform this block using "//"-style comments. Plus a period is missing at the end.
This should apply (unmodified) to 7 too, bumping version.
Comment #15
valthebaldAnother try...
Comment #16
damien tournoud commentedWe are getting there :) Some additional code style issues (including one I missed on first review, sorry):
- The comment line should not cross the 80 character boundary. You will need to split that comment line (for example before "(i.e.").
- We always add a space before and after an operator:
$textgroup=="default"should be$textgroup == "default"Comment #17
valthebald...and once again.
Comment #19
lilou commentedSmall typo catch by Damien :
Comment #20
valthebaldSo, what's the next step? :)
Comment #21
damien tournoud commentedThe patch itself looks good.
I extended the test to cover this case, confirmed that the test fails when run alone and that the patch makes it pass.
Because the test bot was happy earlier (http://testing.drupal.org/pifr/file/1/issue-352121.patch says
Passed: 8866 passes, 0 fails, 0 exceptions), and because the approach got Gabor approval, I'm marking this RTBC right away.Comment #22
nedjoComment #23
webchickCommitted to HEAD, per Gábor.
Marking back to 6.x.
Comment #24
steven jones commentedErr.. I'm fairly sure the CVS commit didn't go smoothly, and the local_test module wasn't added to CVS, so HEAD is broken.
Comment #25
damien tournoud commentedComment #26
mr.baileys+1 Subscribe.
Trying to set up a site with 2 languages using i18n, but we're hampered by the problems outlined in this issue when it comes to translating blocks.
A quick glance does indicate that the above patch did make it into 7.x-dev so not sure what the status of this issue is (should it be backported, or did something go wrong against 7.x-dev?)
Comment #27
steven jones commentedHEAD is fixed now.
Comment #28
gábor hojtsy#19 seems to be the "right" patch for Drupal 6 (it does only include the fix without the test, as Drupal 6 expects), BUT it does not apply anymore. Porting required. If #20 changed the logic as well, then porting that would be desired.
Comment #29
nonsiesubscribing (broke a site upgrading from 6.6 to 6.9)
Comment #30
mr.baileysre-rolled the patch from #19 so it applies to Drupal 6 HEAD again. #21 did not change the logic, only added the tests.
Comment #31
twirlingsky commentedI've applied this patch...but it doesn't seem to solve my problem. I'm am translating a page which has javascript (insert of flash xml slideshow) and it won't display on the translated page - so I'm assuming the code isn't being allow. Any ideas on a way to fix this?
Example: http://cima.laurelterlesky.ca/shipping-logistics (english works fine / spanish won't display)
This is with il8n version 6.1
Comment #32
valthebaldSeems like JS error (XMLFlashSlideshow_v3 not defined), not translation-related. Try to compare JSs loaded for English and Spanish versions
Comment #33
twirlingsky commentedAwesome thanks! It just wasn't picking up the javascript path correctly on the translated pages. off and running now.
Comment #34
ao2 commentedI am using the patch in #30 on drupal-6.12 and works ok for me.
Now I can translate custom blocks, thanks.
Can you please consider applying it to D6 as well?
Regards,
Antonio
Comment #35
gábor hojtsyCommitted to Drupal 6 too, thanks!
Comment #36
pasquallejust a note on the original problem: translation of custom block should be done as node translation. It is wrong to use the string translation functionality to translate blocks.. This idea of translating large blob of text same as simple string translation with t() is absolutely unusable..
So for D6 the right approach would be to create a new block and assign language for that block..
Comment #37
pasquallethis patch is wrong.
WTF? How can I create a new textgroup where the safe string check should be applied?
The check should be applied for every textgroup, if you want to omit the check then you should specially say so (in configuration or hook). It is wrong to omit the check for every textgroup as most of the strings in different textgroups should not contain disallowed html..
Comment #38
gábor hojtsyPasqualle: Features like nodes as blocks is not part of core. Also, as said multiple times above, the non-default textgroups are used for things like blocks, menus, taxonomy, etc, which is assumed to be user input and is therefore filtered or escaped on use.
Comment #39
pasqualleThe block translation is also not part of core. I just say when you want to translate a block it is better to create a new block than using t() on a HTML text blob..
The textgroups should have a format value associated. As format used in views_handler_field_markup in views module. So the strings can be easily checked with
check_markup($value, $format, FALSE);at entry also.Comment #40
pasqualleI correct myself:
the patch is wrongthe patch is not good enough for Drupal 7Comment #42
hass commentedMarked #368173: Full HTML Blocks cannot be translated as a duplicate of this issue.
Comment #43
hass commentedMarked #421228: Blocks html code differs between languages as a duplicate of this issue.
Comment #44
hass commentedMarked #465436: Error: The submitted string contains disallowed HTML as a duplicate of this issue.
Comment #45
Anonymous (not verified) commentedRe-opening as I have this issue in D 6.19.
My English/default block has the following which works well:
However when I use the Translation interface to translate it to Japanese and insert the code below I get "The submitted string contains disallowed HTML":
Strangely enough, the code above is *already* in Drupal translation database as the 'original' text so I think the "disallowed HTML" error may have been fixed earlier in 6.12 but somehow crept back in?
Comment #46
Anonymous (not verified) commentedOk, so I've fixed my issue but I still think there is a bug.
Here's how I fixed my issue:
1- Go to the block list page, click 'configure' next to my custom block. Then click save. (So I'm not really doing anything).
2- Go to the translation interface. Search for the block's string. Click 'edit', click save.
3- All works well now.
So, re-saving the default block seems to have updated something in the DB that now allows the translation string to hold 'disallowed' HMTL ...
Comment #47
my-family commentedThe same problem, but in the "Help text" for CCK field. Re-saving the field does not help, neither the refreshing cck strings for translation.
My string: "Enter your education details. For pasting test from other source (e.g., MS Word) use the icon "Paste text":
. You will find the template text in Employees/Example-name."
It is really important for me to have an icon in the explanation text...
Comment #48
mandreato commentedHi, I have a view with a field using the "Rewrite the output of this field" option. The text to display is a concatenation of other fields:
I need to localize it in another language, but .../admin/build/translate/edit/... form doesn't allow it (because The submitted string contains disallowed HTML).
Am I posting in the right thread (since it is locale.inc giving that error) ?
Or is it a view bug or a i18n bug ?
Thanks in advance.
Comment #49
jose reyero commentedI think this is not a bug, this is some validation that happens on purpose because we need validation for these strings.
Btw, we've added the validation back into i18n translations so the patch here may have 'fixed' the issue for a while for some people, but not anymore. See #1437146: Rework string translation access. (After 1.4 update, block translation disallowed HTML error)
Now if anyone wants translators to submit unfiltered strings, please code your own module and share it (and deal with the related security issues.)
Or if anyone wants to go for a real solution, add proper 'text formats' for these texts so they can be filtered.
Please don't backport it to 6.x because then we'll need to fix i18n for 6.x too.
Comment #50
jose reyero commentedWell, after reading this again, it seems maybe we don't need to care about security for translators, ?, http://drupal.org/node/1471870
Anyway things like backporting these changes to D6 may require some long time running sites to change their security policy and rethink who has the 'translate interface' permission. Just to note it