mirror of
https://github.com/discourse/discourse.git
synced 2025-01-30 23:30:45 +08:00
FEATURE: Allow embedding to ignore HTTP REFERER
New site setting: `embed_any_origin` that will send postMessages to wildcard origins `*` instead of the referer. Most of the time you won't want to do this, so the setting is default to `false`. However, there are certain situations where you want to allow embedding to send post messages when there is no HTTP REFERER. For example, if you created a native mobile app and you wanted to embed a list of Discourse topics as HTML. In the code your HTML would be a static file/string, which would not be able to send a referer. In this case, the site setting will allow the embed to work. From a security standpoint we currently only use `postMessage` to send data about the size of the HTML document and scroll position, so it should be enable if required with minimal security ramifications.
This commit is contained in:
parent
cf23016360
commit
1cebe7670a
|
@ -8,7 +8,7 @@ class EmbedController < ApplicationController
|
||||||
skip_before_action :check_xhr, :preload_json, :verify_authenticity_token
|
skip_before_action :check_xhr, :preload_json, :verify_authenticity_token
|
||||||
|
|
||||||
before_action :ensure_embeddable, except: [ :info, :topics ]
|
before_action :ensure_embeddable, except: [ :info, :topics ]
|
||||||
before_action :get_embeddable_css_class, except: [ :info, :topics ]
|
before_action :prepare_embeddable, except: [ :info ]
|
||||||
before_action :ensure_api_request, only: [ :info ]
|
before_action :ensure_api_request, only: [ :info ]
|
||||||
|
|
||||||
layout 'embed'
|
layout 'embed'
|
||||||
|
@ -123,10 +123,13 @@ class EmbedController < ApplicationController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def get_embeddable_css_class
|
def prepare_embeddable
|
||||||
@embeddable_css_class = ""
|
@embeddable_css_class = ""
|
||||||
embeddable_host = EmbeddableHost.record_for_url(request.referer)
|
embeddable_host = EmbeddableHost.record_for_url(request.referer)
|
||||||
@embeddable_css_class = " class=\"#{embeddable_host.class_name}\"" if embeddable_host.present? && embeddable_host.class_name.present?
|
@embeddable_css_class = " class=\"#{embeddable_host.class_name}\"" if embeddable_host.present? && embeddable_host.class_name.present?
|
||||||
|
|
||||||
|
@data_referer = request.referer
|
||||||
|
@data_referer = '*' if SiteSetting.embed_any_origin? && @data_referer.blank?
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_api_request
|
def ensure_api_request
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<title><%= @topic_view.page_title %> - <%= SiteSetting.title %></title>
|
<title><%= @topic_view.page_title %> - <%= SiteSetting.title %></title>
|
||||||
<%- end %>
|
<%- end %>
|
||||||
|
|
||||||
<meta id="data-embedded" data-referer="<%= request.referer %>">
|
<meta id="data-embedded" data-referer="<%= @data_referer %>">
|
||||||
<%= preload_script 'embed-application' %>
|
<%= preload_script 'embed-application' %>
|
||||||
|
|
||||||
<%= yield :head %>
|
<%= yield :head %>
|
||||||
|
|
|
@ -1959,6 +1959,7 @@ en:
|
||||||
autohighlight_all_code: "Force apply code highlighting to all preformatted code blocks even when they didn't explicitly specify the language."
|
autohighlight_all_code: "Force apply code highlighting to all preformatted code blocks even when they didn't explicitly specify the language."
|
||||||
highlighted_languages: "Included syntax highlighting rules. (Warning: including too many languages may impact performance) see: <a href='https://highlightjs.org/static/demo/' target='_blank'>https://highlightjs.org/static/demo</a> for a demo"
|
highlighted_languages: "Included syntax highlighting rules. (Warning: including too many languages may impact performance) see: <a href='https://highlightjs.org/static/demo/' target='_blank'>https://highlightjs.org/static/demo</a> for a demo"
|
||||||
|
|
||||||
|
embed_any_origin: "Allow embeddable content regardless of origin. This is required for mobile apps with static HTML."
|
||||||
embed_topics_list: "Support HTML embedding of topics lists"
|
embed_topics_list: "Support HTML embedding of topics lists"
|
||||||
embed_truncate: "Truncate the embedded posts."
|
embed_truncate: "Truncate the embedded posts."
|
||||||
embed_support_markdown: "Support Markdown formatting for embedded posts."
|
embed_support_markdown: "Support Markdown formatting for embedded posts."
|
||||||
|
@ -4598,4 +4599,4 @@ en:
|
||||||
html_missing_placeholder: "The html template must include %{placeholder}"
|
html_missing_placeholder: "The html template must include %{placeholder}"
|
||||||
|
|
||||||
discord:
|
discord:
|
||||||
not_in_allowed_guild: 'Authentication failed. You are not a member of a permitted Discord guild.'
|
not_in_allowed_guild: 'Authentication failed. You are not a member of a permitted Discord guild.'
|
||||||
|
|
|
@ -859,6 +859,7 @@ posting:
|
||||||
choices:
|
choices:
|
||||||
- 4-spaces-indent
|
- 4-spaces-indent
|
||||||
- code-fences
|
- code-fences
|
||||||
|
embed_any_origin: false
|
||||||
embed_topics_list: false
|
embed_topics_list: false
|
||||||
embed_truncate:
|
embed_truncate:
|
||||||
default: true
|
default: true
|
||||||
|
|
|
@ -88,12 +88,29 @@ describe EmbedController do
|
||||||
|
|
||||||
it "returns a list of topics" do
|
it "returns a list of topics" do
|
||||||
topic = Fabricate(:topic)
|
topic = Fabricate(:topic)
|
||||||
get '/embed/topics?discourse_embed_id=de-1234', headers: headers
|
get '/embed/topics?discourse_embed_id=de-1234', headers: {
|
||||||
|
'REFERER' => 'https://example.com/evil-trout'
|
||||||
|
}
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
expect(response.headers['X-Frame-Options']).to eq("ALLOWALL")
|
expect(response.headers['X-Frame-Options']).to eq("ALLOWALL")
|
||||||
expect(response.body).to match("data-embed-id=\"de-1234\"")
|
expect(response.body).to match("data-embed-id=\"de-1234\"")
|
||||||
expect(response.body).to match("data-topic-id=\"#{topic.id}\"")
|
expect(response.body).to match("data-topic-id=\"#{topic.id}\"")
|
||||||
|
expect(response.body).to match("data-referer=\"https://example.com/evil-trout\"")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "returns no referer if not supplied" do
|
||||||
|
get '/embed/topics?discourse_embed_id=de-1234'
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
expect(response.body).to match("data-referer=\"\"")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns * for the referer if `embed_any_origin` is set" do
|
||||||
|
SiteSetting.embed_any_origin = true
|
||||||
|
get '/embed/topics?discourse_embed_id=de-1234'
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
expect(response.body).to match("data-referer=\"\\*\"")
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user