mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 10:33:51 +08:00
SECURITY: Onebox templates' HTML injections.
The use of triple-curlies on Mustache templates opens the possibility for HTML injections.
This commit is contained in:
parent
5f20748e40
commit
d78357917c
|
@ -36,7 +36,7 @@ module Onebox
|
|||
body, excerpt = compute_body(raw["body"])
|
||||
ulink = URI(link)
|
||||
|
||||
labels = raw["labels"].map { |l| { name: Emoji.codes_to_img(l["name"]) } }
|
||||
labels = raw["labels"].map { |l| { name: Emoji.codes_to_img(CGI.escapeHTML(l["name"])) } }
|
||||
|
||||
{
|
||||
link: @url,
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
<h3>
|
||||
<a class="badge-wrapper bullet" href="{{url}}">
|
||||
{{#color}}
|
||||
<span class="badge-category-bg" style="background-color: #{{{color}}}"></span>
|
||||
<span class="badge-category-bg" style="background-color: #{{color}}"></span>
|
||||
{{/color}}
|
||||
<span class="clear-badge"><span>{{{name}}}</span></span>
|
||||
<span class="clear-badge"><span>{{name}}</span></span>
|
||||
</a>
|
||||
</h3>
|
||||
{{#description}}
|
||||
<div>
|
||||
<span class="description">
|
||||
<p>{{{description}}}</p>
|
||||
<p>{{description}}</p>
|
||||
</span>
|
||||
</div>
|
||||
{{/description}}
|
||||
|
@ -23,8 +23,8 @@
|
|||
{{#subcategories}}
|
||||
<span class="subcategory">
|
||||
<a class="badge-wrapper bullet" href="{{url}}">
|
||||
<span class="badge-category-bg" style="background-color: #{{{color}}}"></span>
|
||||
<span class="badge-category clear-badge"><span class="category-name">{{{name}}}</span></span>
|
||||
<span class="badge-category-bg" style="background-color: #{{color}}"></span>
|
||||
<span class="badge-category clear-badge"><span class="category-name">{{name}}</span></span>
|
||||
</a>
|
||||
</span>
|
||||
{{/subcategories}}
|
||||
|
|
73
spec/fixtures/onebox/github_issue_onebox.response
vendored
Normal file
73
spec/fixtures/onebox/github_issue_onebox.response
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"url": "https://api.github.com/repos/romanrizzi/avalancha-parser/issues/2",
|
||||
"repository_url": "https://api.github.com/repos/romanrizzi/avalancha-parser",
|
||||
"labels_url": "https://api.github.com/repos/romanrizzi/avalancha-parser/issues/2/labels{/name}",
|
||||
"comments_url": "https://api.github.com/repos/romanrizzi/avalancha-parser/issues/2/comments",
|
||||
"events_url": "https://api.github.com/repos/romanrizzi/avalancha-parser/issues/2/events",
|
||||
"html_url": "https://github.com/romanrizzi/avalancha-parser/issues/2",
|
||||
"id": 1957276127,
|
||||
"node_id": "I_kwDOEdKQe850qanf",
|
||||
"number": 2,
|
||||
"title": "Test issue #2",
|
||||
"user": {
|
||||
"login": "romanrizzi",
|
||||
"id": 5025816,
|
||||
"node_id": "MDQ6VXNlcjUwMjU4MTY=",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/5025816?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/romanrizzi",
|
||||
"html_url": "https://github.com/romanrizzi",
|
||||
"followers_url": "https://api.github.com/users/romanrizzi/followers",
|
||||
"following_url": "https://api.github.com/users/romanrizzi/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/romanrizzi/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/romanrizzi/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/romanrizzi/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/romanrizzi/orgs",
|
||||
"repos_url": "https://api.github.com/users/romanrizzi/repos",
|
||||
"events_url": "https://api.github.com/users/romanrizzi/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/romanrizzi/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"labels": [
|
||||
{
|
||||
"id": 6119137046,
|
||||
"node_id": "LA_kwDOEdKQe88AAAABbLqfFg",
|
||||
"url": "https://api.github.com/repos/romanrizzi/avalancha-parser/labels/Test%20:+1:%20%3Cstyle%3Ebody%20%7Bdisplay:%20none%7D%3C/style%3E",
|
||||
"name": "Test :+1: <style>body {display: none}</style>",
|
||||
"color": "0E8A16",
|
||||
"default": false,
|
||||
"description": ""
|
||||
}
|
||||
],
|
||||
"state": "open",
|
||||
"locked": false,
|
||||
"assignee": null,
|
||||
"assignees": [
|
||||
|
||||
],
|
||||
"milestone": null,
|
||||
"comments": 0,
|
||||
"created_at": "2023-10-23T14:13:07Z",
|
||||
"updated_at": "2023-10-23T14:13:07Z",
|
||||
"closed_at": null,
|
||||
"author_association": "OWNER",
|
||||
"active_lock_reason": null,
|
||||
"body": "test",
|
||||
"closed_by": null,
|
||||
"reactions": {
|
||||
"url": "https://api.github.com/repos/romanrizzi/avalancha-parser/issues/2/reactions",
|
||||
"total_count": 0,
|
||||
"+1": 0,
|
||||
"-1": 0,
|
||||
"laugh": 0,
|
||||
"hooray": 0,
|
||||
"confused": 0,
|
||||
"heart": 0,
|
||||
"rocket": 0,
|
||||
"eyes": 0
|
||||
},
|
||||
"timeline_url": "https://api.github.com/repos/romanrizzi/avalancha-parser/issues/2/timeline",
|
||||
"performed_via_github_app": null,
|
||||
"state_reason": null
|
||||
}
|
24
spec/lib/onebox/engine/github_issue_onebox_spec.rb
Normal file
24
spec/lib/onebox/engine/github_issue_onebox_spec.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Onebox::Engine::GithubIssueOnebox do
|
||||
before do
|
||||
@link = "https://github.com/discourse/discourse/issues/1"
|
||||
|
||||
stub_request(:get, "https://api.github.com/repos/discourse/discourse/issues/1").to_return(
|
||||
status: 200,
|
||||
body: onebox_response("github_issue_onebox"),
|
||||
)
|
||||
end
|
||||
|
||||
include_context "with engines"
|
||||
it_behaves_like "an engine"
|
||||
|
||||
describe "#to_html" do
|
||||
it "sanitizes the input and transform the emoji into an img tag" do
|
||||
sanitized_label =
|
||||
'Test <img src="/images/emoji/twitter/+1.png?v=12" title="+1" class="emoji" alt="+1" loading="lazy" width="20" height="20"> <style>body {display: none}</style>'
|
||||
|
||||
expect(html).to include(sanitized_label)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user