From 17022907866710a72a1b1fc0a5ce9538bad1b4c3 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 7 Jan 2026 14:14:42 +0100 Subject: [PATCH 1/3] Merge commit from fork --- app/lib/private_address_check.rb | 11 +++++++---- spec/lib/private_address_check_spec.rb | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 spec/lib/private_address_check_spec.rb diff --git a/app/lib/private_address_check.rb b/app/lib/private_address_check.rb index d00b16e66b..5c4db6ffae 100644 --- a/app/lib/private_address_check.rb +++ b/app/lib/private_address_check.rb @@ -1,9 +1,7 @@ # frozen_string_literal: true module PrivateAddressCheck - module_function - - CIDR_LIST = [ + IP4_CIDR_LIST = [ IPAddr.new('0.0.0.0/8'), # Current network (only valid as source address) IPAddr.new('100.64.0.0/10'), # Shared Address Space IPAddr.new('172.16.0.0/12'), # Private network @@ -16,6 +14,9 @@ module PrivateAddressCheck IPAddr.new('224.0.0.0/4'), # IP multicast (former Class D network) IPAddr.new('240.0.0.0/4'), # Reserved (former Class E network) IPAddr.new('255.255.255.255'), # Broadcast + ].freeze + + CIDR_LIST = (IP4_CIDR_LIST + IP4_CIDR_LIST.map(&:ipv4_mapped) + [ IPAddr.new('64:ff9b::/96'), # IPv4/IPv6 translation (RFC 6052) IPAddr.new('100::/64'), # Discard prefix (RFC 6666) IPAddr.new('2001::/32'), # Teredo tunneling @@ -25,7 +26,9 @@ module PrivateAddressCheck IPAddr.new('2002::/16'), # 6to4 IPAddr.new('fc00::/7'), # Unique local address IPAddr.new('ff00::/8'), # Multicast - ].freeze + ]).freeze + + module_function def private_address?(address) address.private? || address.loopback? || address.link_local? || CIDR_LIST.any? { |cidr| cidr.include?(address) } diff --git a/spec/lib/private_address_check_spec.rb b/spec/lib/private_address_check_spec.rb new file mode 100644 index 0000000000..ee9f9295d5 --- /dev/null +++ b/spec/lib/private_address_check_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe PrivateAddressCheck do + describe 'private_address?' do + it 'returns true for private addresses' do + # rubocop:disable RSpec/ExpectActual + expect( + [ + '192.168.1.7', + '0.0.0.0', + '127.0.0.1', + '::ffff:0.0.0.1', + ] + ).to all satisfy('return true') { |addr| described_class.private_address?(IPAddr.new(addr)) } + # rubocop:enable RSpec/ExpectActual + end + end +end From 68e30985ca7afdb89af1b2e9dc962e1993dc8076 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 7 Jan 2026 14:15:13 +0100 Subject: [PATCH 2/3] Merge commit from fork --- .../severed_relationships_controller.rb | 2 +- spec/requests/severed_relationships_spec.rb | 27 +++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/controllers/severed_relationships_controller.rb b/app/controllers/severed_relationships_controller.rb index 817abebf62..9371ebf7d0 100644 --- a/app/controllers/severed_relationships_controller.rb +++ b/app/controllers/severed_relationships_controller.rb @@ -26,7 +26,7 @@ class SeveredRelationshipsController < ApplicationController private def set_event - @event = AccountRelationshipSeveranceEvent.find(params[:id]) + @event = AccountRelationshipSeveranceEvent.where(account: current_account).find(params[:id]) end def following_data diff --git a/spec/requests/severed_relationships_spec.rb b/spec/requests/severed_relationships_spec.rb index ac98ab8f94..e0116120cb 100644 --- a/spec/requests/severed_relationships_spec.rb +++ b/spec/requests/severed_relationships_spec.rb @@ -3,9 +3,10 @@ require 'rails_helper' RSpec.describe 'Severed Relationships' do - let(:account_rs_event) { Fabricate :account_relationship_severance_event } + let(:account_rs_event) { Fabricate(:account_relationship_severance_event) } + let(:user) { account_rs_event.account.user } - before { sign_in Fabricate(:user) } + before { sign_in user } describe 'GET /severed_relationships/:id/following' do it 'returns a CSV file with correct data' do @@ -22,6 +23,17 @@ RSpec.describe 'Severed Relationships' do expect(response.body) .to include('Account address') end + + context 'when the user is not the subject of the event' do + let(:user) { Fabricate(:user) } + + it 'returns a 404' do + get following_severed_relationship_path(account_rs_event, format: :csv) + + expect(response) + .to have_http_status(404) + end + end end describe 'GET /severed_relationships/:id/followers' do @@ -39,5 +51,16 @@ RSpec.describe 'Severed Relationships' do expect(response.body) .to include('Account address') end + + context 'when the user is not the subject of the event' do + let(:user) { Fabricate(:user) } + + it 'returns a 404' do + get followers_severed_relationship_path(account_rs_event, format: :csv) + + expect(response) + .to have_http_status(404) + end + end end end From ef4d722d6af8e0e9a25e30bb6c33aa0e14f6951f Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 7 Jan 2026 14:45:02 +0100 Subject: [PATCH 3/3] Bump version to v4.4.11 (#37410) --- CHANGELOG.md | 15 +++++++++++++++ docker-compose.yml | 6 +++--- lib/mastodon/version.rb | 2 +- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 251354f3ce..cce7abfede 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ All notable changes to this project will be documented in this file. +## [4.4.11] - 2026-01-07 + +### Security + +- Fix SSRF protection bypass ([GHSA](https://github.com/mastodon/mastodon/security/advisories/GHSA-xfrj-c749-jxxq)) +- Fix missing ownership check in severed relationships controller ([GHSA](https://github.com/mastodon/mastodon/security/advisories/GHSA-ww85-x9cp-5v24)) + +### Changed + +- Change HTTP Signature verification status from 401 to 503 on temporary failure to get remote actor (#37221 by @ClearlyClaire) + +### Fixed + +- Fix mentions of domain-blocked users being processed (#37257 by @ClearlyClaire) + ## [4.4.10] - 2025-12-08 ### Security diff --git a/docker-compose.yml b/docker-compose.yml index d51625acb2..ae7e22fe83 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -59,7 +59,7 @@ services: web: # You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes # build: . - image: ghcr.io/mastodon/mastodon:v4.4.10 + image: ghcr.io/mastodon/mastodon:v4.4.11 restart: always env_file: .env.production command: bundle exec puma -C config/puma.rb @@ -83,7 +83,7 @@ services: # build: # dockerfile: ./streaming/Dockerfile # context: . - image: ghcr.io/mastodon/mastodon-streaming:v4.4.10 + image: ghcr.io/mastodon/mastodon-streaming:v4.4.11 restart: always env_file: .env.production command: node ./streaming/index.js @@ -102,7 +102,7 @@ services: sidekiq: # You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes # build: . - image: ghcr.io/mastodon/mastodon:v4.4.10 + image: ghcr.io/mastodon/mastodon:v4.4.11 restart: always env_file: .env.production command: bundle exec sidekiq diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index c25f20a170..e0995f78b1 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -13,7 +13,7 @@ module Mastodon end def patch - 10 + 11 end def default_prerelease