Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/stable-4.1' into 4.1.10
Browse files Browse the repository at this point in the history
  • Loading branch information
maa123 committed Sep 30, 2024
2 parents 746bb6b + 9da2711 commit 020c5a5
Show file tree
Hide file tree
Showing 11 changed files with 47 additions and 30 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@ Changelog

All notable changes to this project will be documented in this file.

## [4.1.20] - 2024-09-30

### Security

- Fix ReDoS vulnerability on some Ruby versions ([GHSA-jpxp-r43f-rhvx](https://github.com/mastodon/mastodon/security/advisories/GHSA-jpxp-r43f-rhvx))
- Update dependencies

### Changed

- Change Mastodon to issue correct HTTP signatures by default (#31994 by @ClearlyClaire)

### Fixed

- Fix replies collection being cached improperly
- Fix security context sometimes not being added in LD-Signed activities (#31871 by @ClearlyClaire)
- Fix error when encountering reblog of deleted post in feed rebuild (#32001 by @ClearlyClaire)

## [4.1.19] - 2024-08-16

### Fixed
Expand Down
20 changes: 9 additions & 11 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ GEM
multi_json
encryptor (3.0.0)
erubi (1.12.0)
et-orbi (1.2.7)
et-orbi (1.2.11)
tzinfo
excon (0.95.0)
fabrication (2.30.0)
Expand Down Expand Up @@ -274,7 +274,7 @@ GEM
fog-json (>= 1.0)
ipaddress (>= 0.8)
formatador (0.3.0)
fugit (1.7.1)
fugit (1.7.2)
et-orbi (~> 1, >= 1.2.7)
raabro (~> 1.4)
fuubar (2.5.1)
Expand Down Expand Up @@ -426,7 +426,7 @@ GEM
net-protocol
net-ssh (7.0.1)
nio4r (2.5.9)
nokogiri (1.16.6)
nokogiri (1.16.7)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nsa (0.2.8)
Expand All @@ -445,9 +445,9 @@ GEM
omniauth-rails_csrf_protection (0.1.2)
actionpack (>= 4.2)
omniauth (>= 1.3.1)
omniauth-saml (1.10.3)
omniauth-saml (1.10.5)
omniauth (~> 1.3, >= 1.3.2)
ruby-saml (~> 1.9)
ruby-saml (~> 1.17)
openid_connect (1.4.2)
activemodel
attr_required (>= 1.0.0)
Expand Down Expand Up @@ -493,7 +493,7 @@ GEM
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (5.0.1)
puma (5.6.8)
puma (5.6.9)
nio4r (~> 2.0)
pundit (2.3.0)
activesupport (>= 3.0.0)
Expand Down Expand Up @@ -567,8 +567,7 @@ GEM
responders (3.0.1)
actionpack (>= 5.0)
railties (>= 5.0)
rexml (3.2.8)
strscan (>= 3.0.9)
rexml (3.3.7)
rotp (6.2.0)
rpam2 (4.0.2)
rqrcode (2.1.2)
Expand Down Expand Up @@ -622,8 +621,8 @@ GEM
rubocop (~> 1.33)
rubocop-capybara (~> 2.17)
ruby-progressbar (1.11.0)
ruby-saml (1.13.0)
nokogiri (>= 1.10.5)
ruby-saml (1.17.0)
nokogiri (>= 1.13.10)
rexml
ruby2_keywords (0.0.5)
rufus-scheduler (3.8.2)
Expand Down Expand Up @@ -683,7 +682,6 @@ GEM
redlock (~> 1.0)
strong_migrations (0.7.9)
activerecord (>= 5)
strscan (3.1.0)
swd (1.3.0)
activesupport (>= 3)
attr_required (>= 0.0.5)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/activitypub/replies_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
before_action :set_replies

def index
expires_in 0, public: public_fetch_mode?
expires_in 0, public: @status.distributable? && public_fetch_mode?
render json: replies_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', skip_activities: true
end

Expand Down
9 changes: 8 additions & 1 deletion app/lib/activitypub/linked_data_signature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class ActivityPub::LinkedDataSignature
include JsonLdHelper

CONTEXT = 'https://w3id.org/identity/v1'
SIGNATURE_CONTEXT = 'https://w3id.org/security/v1'

def initialize(json)
@json = json.with_indifferent_access
Expand Down Expand Up @@ -46,7 +47,13 @@ def sign!(creator, sign_with: nil)

signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), to_be_signed))

@json.merge('signature' => options.merge('signatureValue' => signature))
# Mastodon's context is either an array or a single URL
context_with_security = Array(@json['@context'])
context_with_security << 'https://w3id.org/security/v1'
context_with_security.uniq!
context_with_security = context_with_security.first if context_with_security.size == 1

@json.merge('signature' => options.merge('signatureValue' => signature), '@context' => context_with_security)
end

private
Expand Down
4 changes: 2 additions & 2 deletions app/lib/feed_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,8 @@ def build_crutches(receiver_id, statuses)
arr = crutches[:active_mentions][s.id] || []
arr.concat([s.account_id])

if s.reblog?
arr.concat([s.reblog.account_id])
if s.reblog? && s.reblog.present?
arr.push(s.reblog.account_id)
arr.concat(crutches[:active_mentions][s.reblog_of_id] || [])
end

Expand Down
2 changes: 1 addition & 1 deletion app/lib/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def initialize(verb, url, **options)
@url = Addressable::URI.parse(url).normalize
@http_client = options.delete(:http_client)
@allow_local = options.delete(:allow_local)
@full_path = options.delete(:with_query_string)
@full_path = !options.delete(:omit_query_string)
@options = options.merge(socket_class: use_proxy? || @allow_local ? ProxySocket : Socket)
@options = @options.merge(timeout_class: PerOperationWithDeadline, timeout_options: TIMEOUT)
@options = @options.merge(proxy_url) if use_proxy?
Expand Down
4 changes: 2 additions & 2 deletions app/models/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ class Account < ApplicationRecord
trust_level
)

USERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i
MENTION_RE = %r{(?<![=/[:word:]])@((#{USERNAME_RE})(?:@[[:word:].-]+[[:word:]]+)?)}
USERNAME_RE = /[a-z0-9_]+([.-]+[a-z0-9_]+)*/i
MENTION_RE = %r{(?<![=/[:word:]])@((#{USERNAME_RE})(?:@[[:word:]]+([.-]+[[:word:]]+)*)?)}
URL_PREFIX_RE = %r{\Ahttp(s?)://[^/]+}
USERNAME_ONLY_RE = /\A#{USERNAME_RE}\z/i

Expand Down
2 changes: 1 addition & 1 deletion app/services/activitypub/fetch_replies_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def fetch_collection(collection_or_uri)
rescue Mastodon::UnexpectedResponseError => e
raise unless e.response && e.response.code == 401 && Addressable::URI.parse(collection_or_uri).query.present?

fetch_resource_without_id_validation(collection_or_uri, nil, true, request_options: { with_query_string: true })
fetch_resource_without_id_validation(collection_or_uri, nil, true, request_options: { omit_query_string: false })
end
end

Expand Down
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ services:

web:
build: .
image: ghcr.io/mastodon/mastodon:v4.1.19
image: ghcr.io/mastodon/mastodon:v4.1.20
restart: always
env_file: .env.production
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
Expand All @@ -77,7 +77,7 @@ services:

streaming:
build: .
image: ghcr.io/mastodon/mastodon:v4.1.19
image: ghcr.io/mastodon/mastodon:v4.1.20
restart: always
env_file: .env.production
command: node ./streaming
Expand All @@ -95,7 +95,7 @@ services:

sidekiq:
build: .
image: ghcr.io/mastodon/mastodon:v4.1.19
image: ghcr.io/mastodon/mastodon:v4.1.20
restart: always
env_file: .env.production
command: bundle exec sidekiq
Expand Down
2 changes: 1 addition & 1 deletion lib/mastodon/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def minor
end

def patch
19
20
end

def flags
Expand Down
9 changes: 2 additions & 7 deletions spec/lib/activitypub/linked_data_signature_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,11 @@
describe '#sign!' do
subject { described_class.new(raw_json).sign!(sender) }

it 'returns a hash' do
it 'returns a hash with a signature, the expected context, and the signature can be verified', :aggregate_failures do
expect(subject).to be_a Hash
end

it 'contains signature' do
expect(subject['signature']).to be_a Hash
expect(subject['signature']['signatureValue']).to be_present
end

it 'can be verified again' do
expect(Array(subject['@context'])).to include('https://w3id.org/security/v1')
expect(described_class.new(subject).verify_actor!).to eq sender
end
end
Expand Down

0 comments on commit 020c5a5

Please sign in to comment.