Merge branch 'asonix/changes' into asonix/downstream
This commit is contained in:
commit
16828887b8
|
@ -1,3 +1,7 @@
|
|||
## 2.5.2
|
||||
|
||||
- Fix XSS vulnerability (#8959)
|
||||
|
||||
## 2.5.1
|
||||
|
||||
- Fix some local images not having their EXIF metadata stripped on upload (#8714)
|
||||
|
|
|
@ -22,6 +22,12 @@ module SignatureVerification
|
|||
return
|
||||
end
|
||||
|
||||
if request.headers['Date'].present? && !matches_time_window?
|
||||
@signature_verification_failure_reason = 'Signed request date outside acceptable time window'
|
||||
@signed_request_account = nil
|
||||
return
|
||||
end
|
||||
|
||||
raw_signature = request.headers['Signature']
|
||||
signature_params = {}
|
||||
|
||||
|
@ -76,7 +82,7 @@ module SignatureVerification
|
|||
def build_signed_string(signed_headers)
|
||||
signed_headers = 'date' if signed_headers.blank?
|
||||
|
||||
signed_headers.split(' ').map do |signed_header|
|
||||
signed_headers.downcase.split(' ').map do |signed_header|
|
||||
if signed_header == Request::REQUEST_TARGET
|
||||
"#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}"
|
||||
elsif signed_header == 'digest'
|
||||
|
@ -89,12 +95,12 @@ module SignatureVerification
|
|||
|
||||
def matches_time_window?
|
||||
begin
|
||||
time_sent = DateTime.httpdate(request.headers['Date'])
|
||||
time_sent = Time.httpdate(request.headers['Date'])
|
||||
rescue ArgumentError
|
||||
return false
|
||||
end
|
||||
|
||||
(Time.now.utc - time_sent).abs <= 30
|
||||
(Time.now.utc - time_sent).abs <= 12.hours
|
||||
end
|
||||
|
||||
def body_digest
|
||||
|
|
|
@ -90,8 +90,12 @@ class Formatter
|
|||
|
||||
private
|
||||
|
||||
def html_entities
|
||||
@html_entities ||= HTMLEntities.new
|
||||
end
|
||||
|
||||
def encode(html)
|
||||
HTMLEntities.new.encode(html)
|
||||
html_entities.encode(html)
|
||||
end
|
||||
|
||||
def encode_and_link_urls(html, accounts = nil, options = {})
|
||||
|
@ -143,7 +147,7 @@ class Formatter
|
|||
emoji = emoji_map[shortcode]
|
||||
|
||||
if emoji
|
||||
replacement = "<img draggable=\"false\" class=\"emojione\" alt=\":#{shortcode}:\" title=\":#{shortcode}:\" src=\"#{emoji}\" />"
|
||||
replacement = "<img draggable=\"false\" class=\"emojione\" alt=\":#{encode(shortcode)}:\" title=\":#{encode(shortcode)}:\" src=\"#{encode(emoji)}\" />"
|
||||
before_html = shortname_start_index.positive? ? html[0..shortname_start_index - 1] : ''
|
||||
html = before_html + replacement + html[i + 1..-1]
|
||||
i += replacement.size - (shortcode.size + 2) - 1
|
||||
|
@ -254,7 +258,7 @@ class Formatter
|
|||
end
|
||||
|
||||
account = linkable_accounts.find { |item| TagManager.instance.same_acct?(item.acct, acct) }
|
||||
account ? mention_html(account) : "@#{acct}"
|
||||
account ? mention_html(account) : "@#{encode(acct)}"
|
||||
end
|
||||
|
||||
def link_to_twitter(username)
|
||||
|
@ -339,7 +343,7 @@ class Formatter
|
|||
domain = nil if TagManager.instance.local_domain?(domain)
|
||||
account = EntityCache.instance.mention(username, domain)
|
||||
|
||||
account ? mention_html(account) : "@#{acct}"
|
||||
account ? mention_html(account) : "@#{encode(acct)}"
|
||||
end
|
||||
|
||||
def link_to_hashtag(entity)
|
||||
|
@ -357,10 +361,10 @@ class Formatter
|
|||
end
|
||||
|
||||
def hashtag_html(tag)
|
||||
"<a href=\"#{tag_url(tag.downcase)}\" class=\"mention hashtag\" rel=\"tag\">#<span>#{tag}</span></a>"
|
||||
"<a href=\"#{encode(tag_url(tag.downcase))}\" class=\"mention hashtag\" rel=\"tag\">#<span>#{encode(tag)}</span></a>"
|
||||
end
|
||||
|
||||
def mention_html(account)
|
||||
"<span class=\"h-card\"><a href=\"#{TagManager.instance.url_for(account)}\" class=\"u-url mention\">@<span>#{account.username}</span></a></span>"
|
||||
"<span class=\"h-card\"><a href=\"#{encode(TagManager.instance.url_for(account))}\" class=\"u-url mention\">@<span>#{encode(account.username)}</span></a></span>"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@ module Mastodon
|
|||
end
|
||||
|
||||
def patch
|
||||
1
|
||||
2
|
||||
end
|
||||
|
||||
def pre
|
||||
|
|
|
@ -73,6 +73,30 @@ describe ApplicationController, type: :controller do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with request older than a day' do
|
||||
before do
|
||||
get :success
|
||||
|
||||
fake_request = Request.new(:get, request.url)
|
||||
fake_request.add_headers({ 'Date' => 2.days.ago.utc.httpdate })
|
||||
fake_request.on_behalf_of(author)
|
||||
|
||||
request.headers.merge!(fake_request.headers)
|
||||
end
|
||||
|
||||
describe '#signed_request?' do
|
||||
it 'returns true' do
|
||||
expect(controller.signed_request?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
describe '#signed_request_account' do
|
||||
it 'returns nil' do
|
||||
expect(controller.signed_request_account).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with body' do
|
||||
before do
|
||||
post :success, body: 'Hello world'
|
||||
|
|
Loading…
Reference in a new issue