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
content_tag(:h4, headline) <<
content_tag(:ul) do
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)
content_tag(:li, message)
......
......@@ -21,7 +21,7 @@ class HtmlSafetyValidator < ActiveModel::EachValidator
end
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
private
......
......@@ -10,7 +10,7 @@
= sprite_icon('close', size: 16, css_class: 'gl-icon')
.gl-alert-body
%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
= 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 @@
%tbody
- @u2f_registrations.each do |registration|
%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= 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 @@
- 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_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
= 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>')
- run_actions_text = s_("ProjectService|Perform common operations on GitLab project: %{project_name}") % { project_name: pretty_name }
- pretty_name = @project&.full_name || _('&lt;project name&gt;')
- run_actions_text = html_escape_once(s_("ProjectService|Perform common operations on GitLab project: %{project_name}") % { project_name: pretty_name })
.info-well
.well-segment
......@@ -67,7 +67,7 @@
.form-group
= label_tag :autocomplete_description, _('Autocomplete description'), class: 'col-12 col-form-label label-bold'
.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
= clipboard_button(target: '#autocomplete_description', class: 'input-group-text')
......
......@@ -42,7 +42,7 @@
= _('In %{time_to_now}') % { time_to_now: distance_of_time_in_words_to_now(token.expires_at) }
- else
%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 } }
- else
.settings-message.text-center
......
......@@ -23,7 +23,7 @@
In #{distance_of_time_in_words_to_now(token.expires_at)}
- else
%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}"}
= render 'shared/deploy_tokens/revoke_modal', token: token, group_or_project: group_or_project
- else
......
......@@ -74,50 +74,6 @@
- "< 1 hora"
- "< 1 saat"
- "< 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.":
plural_id:
translations:
......@@ -1053,3 +1009,47 @@
- "아래 프로젝트 목록에서 <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."
- "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 ""
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 ""
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"
msgstr ""
......@@ -1016,12 +1025,6 @@ msgstr ""
msgid "<code>Protected</code> to expose them to protected branches or tags only."
msgstr ""
msgid "<no name set>"
msgstr ""
msgid "<no scopes selected>"
msgstr ""
msgid "<project name>"
msgstr ""
......@@ -1723,7 +1726,7 @@ msgstr ""
msgid "AdminSettings|Auto DevOps domain"
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 ""
msgid "AdminSettings|Enable shared runners for new projects"
......@@ -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}."
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 ""
msgid "GitLabPages|Access pages"
......@@ -27734,7 +27737,7 @@ msgstr ""
msgid "cannot block others"
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 ""
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