Ingested t() strings are normally validated on input for XSS (as opposed to user input that's filtered on output)
For example in D7: https://api.drupal.org/api/drupal/modules%21locale%21locale.admin.inc/fu... calls to https://api.drupal.org/api/drupal/includes%21locale.inc/function/locale_...
This validation needs to be applied to all strings submitted for config translation.
Example STR:
1. add a second language
2. give user A permission 'translate configuration'
3. as user A go to /admin/structure/comment/manage/comment/fields/comment.comment.comment_body/translate
4. add translation and fill label textfield with payload
5. script will trigger if admin visits /admin/config/regional/config-translation/comment_fields in the target language
Analysis thanks to Gabor Hojtsy:
the call stack of ConfigTranslationListController::listing() goes to EntityType::getLabel() which is a (string) $this->label and $this->label is…. a TranslationWrapper
it is a TranslationWrapper but is not with an already translated string… basically it translates the entity type “Comment”, and because we got in XSS via the config translation UI, we got a resulting string that is not safe, even though t() adds results to safe markup
Issues related to this were reported multiple times in the Drupal 8 security bug bounty program, including:
https://tracker.bugcrowd.com/submissions/5784d8a9dc93ce674776af30bf97f49...
https://tracker.bugcrowd.com/submissions/672a7ac983d1d6e554114e2f287824a...
credit to users:
JvE
grisendo