2021-05-26 05:41:35 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2022-04-06 09:19:41 -04:00
|
|
|
module Onebox
|
|
|
|
module SanitizeConfig
|
2021-05-26 05:41:35 -04:00
|
|
|
HTTP_PROTOCOLS ||= ["http", "https", :relative].freeze
|
|
|
|
|
2022-04-06 09:19:41 -04:00
|
|
|
ONEBOX ||=
|
|
|
|
Sanitize::Config.freeze_config(
|
|
|
|
Sanitize::Config.merge(
|
|
|
|
Sanitize::Config::RELAXED,
|
|
|
|
elements:
|
|
|
|
Sanitize::Config::RELAXED[:elements] +
|
2022-11-24 10:28:21 -05:00
|
|
|
%w[audio details embed iframe source video svg path use],
|
2021-05-26 05:41:35 -04:00
|
|
|
attributes: {
|
2022-04-06 09:19:41 -04:00
|
|
|
"a" => Sanitize::Config::RELAXED[:attributes]["a"] + %w[target],
|
2021-05-26 05:41:35 -04:00
|
|
|
"audio" => %w[controls controlslist],
|
|
|
|
"embed" => %w[height src type width],
|
|
|
|
"iframe" => %w[
|
|
|
|
allowfullscreen
|
|
|
|
frameborder
|
|
|
|
height
|
|
|
|
scrolling
|
|
|
|
src
|
|
|
|
width
|
|
|
|
data-original-href
|
|
|
|
data-unsanitized-src
|
|
|
|
],
|
|
|
|
"source" => %w[src type],
|
|
|
|
"video" => %w[
|
|
|
|
controls
|
|
|
|
height
|
|
|
|
loop
|
|
|
|
width
|
|
|
|
autoplay
|
|
|
|
muted
|
2023-01-09 07:10:19 -05:00
|
|
|
poster
|
2021-05-26 05:41:35 -04:00
|
|
|
controlslist
|
|
|
|
playsinline
|
|
|
|
],
|
|
|
|
"path" => %w[d fill-rule],
|
|
|
|
"svg" => %w[aria-hidden width height viewbox],
|
|
|
|
"div" => [:data], # any data-* attributes,
|
2022-11-24 10:28:21 -05:00
|
|
|
"span" => [:data], # any data-* attributes,
|
|
|
|
"use" => %w[href],
|
2023-01-09 07:10:19 -05:00
|
|
|
},
|
2022-04-06 09:19:41 -04:00
|
|
|
add_attributes: {
|
2021-05-26 05:41:35 -04:00
|
|
|
"iframe" => {
|
|
|
|
"seamless" => "seamless",
|
|
|
|
"sandbox" =>
|
|
|
|
"allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox" \
|
|
|
|
" allow-presentation",
|
|
|
|
},
|
|
|
|
},
|
2022-04-06 09:19:41 -04:00
|
|
|
transformers:
|
|
|
|
(Sanitize::Config::RELAXED[:transformers] || []) +
|
|
|
|
[
|
2021-05-26 05:41:35 -04:00
|
|
|
lambda do |env|
|
|
|
|
next unless env[:node_name] == "a"
|
|
|
|
a_tag = env[:node]
|
|
|
|
a_tag["href"] ||= "#"
|
|
|
|
if a_tag["href"] =~ %r{^(?:[a-z]+:)?//}
|
|
|
|
a_tag["rel"] = "nofollow ugc noopener"
|
|
|
|
else
|
|
|
|
a_tag.remove_attribute("target")
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
lambda do |env|
|
|
|
|
next unless env[:node_name] == "iframe"
|
|
|
|
|
|
|
|
iframe = env[:node]
|
|
|
|
allowed_regexes = env[:config][:allowed_iframe_regexes] || [/.*/]
|
|
|
|
|
|
|
|
allowed = allowed_regexes.any? { |r| iframe["src"] =~ r }
|
|
|
|
|
|
|
|
if !allowed
|
|
|
|
# add a data attribute with the blocked src. This is not required
|
|
|
|
# but makes it much easier to troubleshoot onebox issues
|
|
|
|
iframe["data-unsanitized-src"] = iframe["src"]
|
|
|
|
iframe.remove_attribute("src")
|
2023-01-09 07:10:19 -05:00
|
|
|
end
|
|
|
|
end,
|
|
|
|
],
|
2021-05-26 05:41:35 -04:00
|
|
|
protocols: {
|
2023-01-09 07:10:19 -05:00
|
|
|
"embed" => {
|
2021-05-26 05:41:35 -04:00
|
|
|
"src" => HTTP_PROTOCOLS,
|
2023-01-09 07:10:19 -05:00
|
|
|
},
|
|
|
|
"iframe" => {
|
2021-05-26 05:41:35 -04:00
|
|
|
"src" => HTTP_PROTOCOLS,
|
2023-01-09 07:10:19 -05:00
|
|
|
},
|
2021-05-26 05:41:35 -04:00
|
|
|
"source" => {
|
|
|
|
"src" => HTTP_PROTOCOLS,
|
2023-01-09 07:10:19 -05:00
|
|
|
},
|
2022-11-24 10:28:21 -05:00
|
|
|
"use" => {
|
|
|
|
"href" => [:relative],
|
|
|
|
},
|
2023-01-09 07:10:19 -05:00
|
|
|
},
|
2021-05-26 05:41:35 -04:00
|
|
|
css: {
|
2022-04-06 09:19:41 -04:00
|
|
|
properties: Sanitize::Config::RELAXED[:css][:properties] + %w[--aspect-ratio],
|
2021-05-26 05:41:35 -04:00
|
|
|
},
|
2023-01-09 07:10:19 -05:00
|
|
|
),
|
2022-04-06 09:19:41 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
DISCOURSE_ONEBOX ||=
|
|
|
|
Sanitize::Config.freeze_config(
|
|
|
|
Sanitize::Config.merge(
|
|
|
|
ONEBOX,
|
|
|
|
attributes: Sanitize::Config.merge(ONEBOX[:attributes], "aside" => [:data]),
|
|
|
|
),
|
|
|
|
)
|
2021-05-26 05:41:35 -04:00
|
|
|
end
|
|
|
|
end
|