Commit b8f402c5 authored by Josianne Hyson's avatar Josianne Hyson

Replace angle brackets in translations with HTML entity code

We no longer allow any angle brackets in translations to avoid XSS
attacks via the translations. Replace the usage of < and > in these
strings so that they can be translated again.

Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/228846
parent 0f78d17b
...@@ -11,7 +11,7 @@ module FormHelper ...@@ -11,7 +11,7 @@ module FormHelper
content_tag(:h4, headline) << content_tag(:h4, headline) <<
content_tag(:ul) do content_tag(:ul) do
messages = model.errors.map do |attribute, message| messages = model.errors.map do |attribute, message|
message = model.errors.full_message(attribute, message) message = html_escape_once(model.errors.full_message(attribute, message)).html_safe
message = content_tag(:span, message, class: 'str-truncated-100') if truncate.include?(attribute) message = content_tag(:span, message, class: 'str-truncated-100') if truncate.include?(attribute)
content_tag(:li, message) content_tag(:li, message)
......
...@@ -21,7 +21,7 @@ class HtmlSafetyValidator < ActiveModel::EachValidator ...@@ -21,7 +21,7 @@ class HtmlSafetyValidator < ActiveModel::EachValidator
end end
def self.error_message def self.error_message
_("cannot contain HTML/XML tags, including any word between angle brackets (<,>).") _("cannot contain HTML/XML tags, including any word between angle brackets (&lt;,&gt;).")
end end
private private
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
= sprite_icon('close', size: 16, css_class: 'gl-icon') = sprite_icon('close', size: 16, css_class: 'gl-icon')
.gl-alert-body .gl-alert-body
%h4.gl-alert-title= s_('AdminSettings|Some settings have moved') %h4.gl-alert-title= s_('AdminSettings|Some settings have moved')
= s_('AdminSettings|Elasticsearch, PlantUML, Slack application, Third party offers, Snowplow, Amazon EKS have moved to Settings > General.') = html_escape_once(s_('AdminSettings|Elasticsearch, PlantUML, Slack application, Third party offers, Snowplow, Amazon EKS have moved to Settings &gt; General.')).html_safe
.gl-alert-actions .gl-alert-actions
= link_to s_('AdminSettings|Go to General Settings'), general_admin_application_settings_path, class: 'btn gl-alert-action btn-info new-gl-button' = link_to s_('AdminSettings|Go to General Settings'), general_admin_application_settings_path, class: 'btn gl-alert-action btn-info new-gl-button'
......
...@@ -88,7 +88,7 @@ ...@@ -88,7 +88,7 @@
%tbody %tbody
- @u2f_registrations.each do |registration| - @u2f_registrations.each do |registration|
%tr %tr
%td= registration.name.presence || _("<no name set>") %td= registration.name.presence || html_escape_once(_("&lt;no name set&gt;")).html_safe
%td= registration.created_at.to_date.to_s(:medium) %td= registration.created_at.to_date.to_s(:medium)
%td= link_to _('Delete'), profile_u2f_registration_path(registration), method: :delete, class: "btn btn-danger float-right", data: { confirm: _('Are you sure you want to delete this device? This action cannot be undone.') } %td= link_to _('Delete'), profile_u2f_registration_path(registration), method: :delete, class: "btn btn-danger float-right", data: { confirm: _('Are you sure you want to delete this device? This action cannot be undone.') }
......
...@@ -18,6 +18,6 @@ ...@@ -18,6 +18,6 @@
- help_page = help_page_path('/user/project/pages/pages_access_control') - help_page = help_page_path('/user/project/pages/pages_access_control')
- link_start = '<a href="%{url}" target="_blank" class="alert-link" rel="noopener noreferrer">'.html_safe % { url: help_page } - link_start = '<a href="%{url}" target="_blank" class="alert-link" rel="noopener noreferrer">'.html_safe % { url: help_page }
- link_end = '</a>'.html_safe - link_end = '</a>'.html_safe
= s_('GitLabPages|Access Control is enabled for this Pages website; only authorized users will be able to access it. To make your website publicly available, navigate to your project\'s %{strong_start}Settings > General > Visibility%{strong_end} and select %{strong_start}Everyone%{strong_end} in pages section. Read the %{link_start}documentation%{link_end} for more information.').html_safe % { link_start: link_start, link_end: link_end, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe } = html_escape_once(s_('GitLabPages|Access Control is enabled for this Pages website; only authorized users will be able to access it. To make your website publicly available, navigate to your project\'s %{strong_start}Settings &gt; General &gt; Visibility%{strong_end} and select %{strong_start}Everyone%{strong_end} in pages section. Read the %{link_start}documentation%{link_end} for more information.')).html_safe % { link_start: link_start, link_end: link_end, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe }
.card-footer.alert-primary .card-footer.alert-primary
= s_('GitLabPages|It may take up to 30 minutes before the site is available after the first deployment.') = s_('GitLabPages|It may take up to 30 minutes before the site is available after the first deployment.')
- pretty_name = @project&.full_name || _('<project name>') - pretty_name = @project&.full_name || _('&lt;project name&gt;')
- run_actions_text = s_("ProjectService|Perform common operations on GitLab project: %{project_name}") % { project_name: pretty_name } - run_actions_text = html_escape_once(s_("ProjectService|Perform common operations on GitLab project: %{project_name}") % { project_name: pretty_name })
.info-well .info-well
.well-segment .well-segment
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
.form-group .form-group
= label_tag :autocomplete_description, _('Autocomplete description'), class: 'col-12 col-form-label label-bold' = label_tag :autocomplete_description, _('Autocomplete description'), class: 'col-12 col-form-label label-bold'
.col-12.input-group .col-12.input-group
= text_field_tag :autocomplete_description, run_actions_text, class: 'form-control form-control-sm', readonly: 'readonly' = text_field_tag :autocomplete_description, run_actions_text.html_safe, class: 'form-control form-control-sm', readonly: 'readonly'
.input-group-append .input-group-append
= clipboard_button(target: '#autocomplete_description', class: 'input-group-text') = clipboard_button(target: '#autocomplete_description', class: 'input-group-text')
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
= _('In %{time_to_now}') % { time_to_now: distance_of_time_in_words_to_now(token.expires_at) } = _('In %{time_to_now}') % { time_to_now: distance_of_time_in_words_to_now(token.expires_at) }
- else - else
%span.token-never-expires-label= _('Never') %span.token-never-expires-label= _('Never')
%td= token.scopes.present? ? token.scopes.join(', ') : _('<no scopes selected>') %td= token.scopes.present? ? token.scopes.join(', ') : html_escape_once(_('&lt;no scopes selected&gt;')).html_safe
%td= link_to _('Revoke'), revoke_route_helper.call(token), method: :put, class: 'btn btn-danger float-right qa-revoke-button', data: { confirm: _('Are you sure you want to revoke this %{type}? This action cannot be undone.') % { type: type } } %td= link_to _('Revoke'), revoke_route_helper.call(token), method: :put, class: 'btn btn-danger float-right qa-revoke-button', data: { confirm: _('Are you sure you want to revoke this %{type}? This action cannot be undone.') % { type: type } }
- else - else
.settings-message.text-center .settings-message.text-center
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
In #{distance_of_time_in_words_to_now(token.expires_at)} In #{distance_of_time_in_words_to_now(token.expires_at)}
- else - else
%span.token-never-expires-label= _('Never') %span.token-never-expires-label= _('Never')
%td= token.scopes.present? ? token.scopes.join(", ") : _('<no scopes selected>') %td= token.scopes.present? ? token.scopes.join(", ") : html_escape_once(_('&lt;no scopes selected&gt;')).html_safe
%td= link_to s_('DeployTokens|Revoke'), "#", class: "btn btn-danger float-right", data: { toggle: "modal", target: "#revoke-modal-#{token.id}"} %td= link_to s_('DeployTokens|Revoke'), "#", class: "btn btn-danger float-right", data: { toggle: "modal", target: "#revoke-modal-#{token.id}"}
= render 'shared/deploy_tokens/revoke_modal', token: token, group_or_project: group_or_project = render 'shared/deploy_tokens/revoke_modal', token: token, group_or_project: group_or_project
- else - else
......
...@@ -74,50 +74,6 @@ ...@@ -74,50 +74,6 @@
- "< 1 hora" - "< 1 hora"
- "< 1 saat" - "< 1 saat"
- "< 1 Stunde" - "< 1 Stunde"
"<namespace / project>":
plural_id:
translations:
- "<namespace / project>"
- "<простір імен / проєкт>"
"<no name set>":
translations:
- "<nenhum nome definido>"
- "<no name set>"
- "<未設定名稱>"
- "<nenhum nome definido>"
- "<no name set>"
- "<未设置名称>"
- "<ім’я не задане>"
- "<no name set>"
- "<sense nom establert>"
- "<no tiene el nombre establecido>"
- "<isim belirlenmemiş>"
"<no scopes selected>":
translations:
- "<nenhum escopo selecionado>"
- "<スコープが選択されていません>"
- "<未選擇範圍>"
- "<nenhum escopo selecionado>"
- "<no scopes selected>"
- "<未选择范围>"
- "<область дії не вибрано>"
- "<keine Bereiche ausgewählt>"
- "<ningún alcance seleccionado>"
- "<hiçbir kapsam seçilmedi>"
"<project name>":
translations:
- "<название проекта>"
- "<project name>"
- "<proje adı>"
- "<naziv projekta>"
- "<ім’я проєкту>"
"AdminSettings|Elasticsearch, PlantUML, Slack application, Third party offers, Snowplow, Amazon EKS have moved to Settings > General.":
translations:
- "Elasticsearch、PlantUML、Slackアプリケーション、サードパーティのオファー、Snowplow、Amazon EKS 設定 > 全般 に移動しました。"
- "Elasticsearch, PlantUML, приложение Slack, предложения от третьих лиц, Snowplow, Amazon EKS были перемещены в Настройки > Общие"
- "Elasticsearch, PlantUML, застосунок Slack, пропозиції від третіх осіб, Snowplow, Amazon EKS були переміщені до Налаштувань > Загальне."
"cannot contain HTML/XML tags, including any word between angle brackets (<,>).":
translations:
"<code>\\\"johnsmith@example.com\\\": \\\"@johnsmith\\\"</code> will add \\\"By <a href=\\\"#\\\">@johnsmith</a>\\\" to all issues and comments originally created by johnsmith@example.com, and will set <a href=\\\"#\\\">@johnsmith</a> as the assignee on all issues originally assigned to johnsmith@example.com.": "<code>\\\"johnsmith@example.com\\\": \\\"@johnsmith\\\"</code> will add \\\"By <a href=\\\"#\\\">@johnsmith</a>\\\" to all issues and comments originally created by johnsmith@example.com, and will set <a href=\\\"#\\\">@johnsmith</a> as the assignee on all issues originally assigned to johnsmith@example.com.":
plural_id: plural_id:
translations: translations:
...@@ -1053,3 +1009,47 @@ ...@@ -1053,3 +1009,47 @@
- "아래 프로젝트 목록에서 <strong>프로젝트 이름</strong>을 눌러 프로젝트 마일스톤을 봅니다." - "아래 프로젝트 목록에서 <strong>프로젝트 이름</strong>을 눌러 프로젝트 마일스톤을 봅니다."
- "Cliquez sur n’importe quel <strong>nom de projet</strong> dans la liste des projets ci‐dessous pour naviguer jusqu’au jalon du projet." - "Cliquez sur n’importe quel <strong>nom de projet</strong> dans la liste des projets ci‐dessous pour naviguer jusqu’au jalon du projet."
- "Haga clic en cualquier <strong>nombre de proyecto</strong> en la lista de proyectos que se muestra a continuación para navegar hasta el hito de proyecto correspondiente." - "Haga clic en cualquier <strong>nombre de proyecto</strong> en la lista de proyectos que se muestra a continuación para navegar hasta el hito de proyecto correspondiente."
"<namespace / project>":
plural_id:
translations:
- "<namespace / project>"
- "<простір імен / проєкт>"
"<no name set>":
translations:
- "<nenhum nome definido>"
- "<no name set>"
- "<未設定名稱>"
- "<nenhum nome definido>"
- "<no name set>"
- "<未设置名称>"
- "<ім’я не задане>"
- "<no name set>"
- "<sense nom establert>"
- "<no tiene el nombre establecido>"
- "<isim belirlenmemiş>"
"<no scopes selected>":
translations:
- "<nenhum escopo selecionado>"
- "<スコープが選択されていません>"
- "<未選擇範圍>"
- "<nenhum escopo selecionado>"
- "<no scopes selected>"
- "<未选择范围>"
- "<область дії не вибрано>"
- "<keine Bereiche ausgewählt>"
- "<ningún alcance seleccionado>"
- "<hiçbir kapsam seçilmedi>"
"<project name>":
translations:
- "<название проекта>"
- "<project name>"
- "<proje adı>"
- "<naziv projekta>"
- "<ім’я проєкту>"
"AdminSettings|Elasticsearch, PlantUML, Slack application, Third party offers, Snowplow, Amazon EKS have moved to Settings > General.":
translations:
- "Elasticsearch、PlantUML、Slackアプリケーション、サードパーティのオファー、Snowplow、Amazon EKS 設定 > 全般 に移動しました。"
- "Elasticsearch, PlantUML, приложение Slack, предложения от третьих лиц, Snowplow, Amazon EKS были перемещены в Настройки > Общие"
- "Elasticsearch, PlantUML, застосунок Slack, пропозиції від третіх осіб, Snowplow, Amazon EKS були переміщені до Налаштувань > Загальне."
"cannot contain HTML/XML tags, including any word between angle brackets (<,>).":
translations:
...@@ -759,6 +759,15 @@ msgstr "" ...@@ -759,6 +759,15 @@ msgstr ""
msgid "%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project. We recommend using an %{integrations_link_start}integration%{link_end} in preference to a webhook." msgid "%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project. We recommend using an %{integrations_link_start}integration%{link_end} in preference to a webhook."
msgstr "" msgstr ""
msgid "&lt;no name set&gt;"
msgstr ""
msgid "&lt;no scopes selected&gt;"
msgstr ""
msgid "&lt;project name&gt;"
msgstr ""
msgid "'%{level}' is not a valid visibility level" msgid "'%{level}' is not a valid visibility level"
msgstr "" msgstr ""
...@@ -1016,12 +1025,6 @@ msgstr "" ...@@ -1016,12 +1025,6 @@ msgstr ""
msgid "<code>Protected</code> to expose them to protected branches or tags only." msgid "<code>Protected</code> to expose them to protected branches or tags only."
msgstr "" msgstr ""
msgid "<no name set>"
msgstr ""
msgid "<no scopes selected>"
msgstr ""
msgid "<project name>" msgid "<project name>"
msgstr "" msgstr ""
...@@ -1723,7 +1726,7 @@ msgstr "" ...@@ -1723,7 +1726,7 @@ msgstr ""
msgid "AdminSettings|Auto DevOps domain" msgid "AdminSettings|Auto DevOps domain"
msgstr "" msgstr ""
msgid "AdminSettings|Elasticsearch, PlantUML, Slack application, Third party offers, Snowplow, Amazon EKS have moved to Settings > General." msgid "AdminSettings|Elasticsearch, PlantUML, Slack application, Third party offers, Snowplow, Amazon EKS have moved to Settings &gt; General."
msgstr "" msgstr ""
msgid "AdminSettings|Enable shared runners for new projects" msgid "AdminSettings|Enable shared runners for new projects"
...@@ -11236,7 +11239,7 @@ msgstr "" ...@@ -11236,7 +11239,7 @@ msgstr ""
msgid "GitLabPages|%{domain} is not verified. To learn how to verify ownership, visit your %{link_start}domain details%{link_end}." msgid "GitLabPages|%{domain} is not verified. To learn how to verify ownership, visit your %{link_start}domain details%{link_end}."
msgstr "" msgstr ""
msgid "GitLabPages|Access Control is enabled for this Pages website; only authorized users will be able to access it. To make your website publicly available, navigate to your project's %{strong_start}Settings > General > Visibility%{strong_end} and select %{strong_start}Everyone%{strong_end} in pages section. Read the %{link_start}documentation%{link_end} for more information." msgid "GitLabPages|Access Control is enabled for this Pages website; only authorized users will be able to access it. To make your website publicly available, navigate to your project's %{strong_start}Settings &gt; General &gt; Visibility%{strong_end} and select %{strong_start}Everyone%{strong_end} in pages section. Read the %{link_start}documentation%{link_end} for more information."
msgstr "" msgstr ""
msgid "GitLabPages|Access pages" msgid "GitLabPages|Access pages"
...@@ -27734,7 +27737,7 @@ msgstr "" ...@@ -27734,7 +27737,7 @@ msgstr ""
msgid "cannot block others" msgid "cannot block others"
msgstr "" msgstr ""
msgid "cannot contain HTML/XML tags, including any word between angle brackets (<,>)." msgid "cannot contain HTML/XML tags, including any word between angle brackets (&lt;,&gt;)."
msgstr "" msgstr ""
msgid "cannot include leading slash or directory traversal." msgid "cannot include leading slash or directory traversal."
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment