Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,39 @@

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

## [4.5.10] - 2026-05-20

### Security

- Fix SSRF protection bypass ([GHSA-crr4-7rm4-8gpw](https://github.com/mastodon/mastodon/security/advisories/GHSA-crr4-7rm4-8gpw), [GHSA-xx55-4rrg-8xg6](https://github.com/mastodon/mastodon/security/advisories/GHSA-xx55-4rrg-8xg6))
- Fix Linked-Data Signature bypass through JSON-LD graph restructuring features ([GHSA-53m7-2wrh-q839](https://github.com/mastodon/mastodon/security/advisories/GHSA-53m7-2wrh-q839), [GHSA-chgx-jx3p-rf73](https://github.com/mastodon/mastodon/security/advisories/GHSA-chgx-jx3p-rf73))
- Updated dependencies

### Fixed

- Fix type of `interactingObject`, `interactionTarget` and add missing `QuoteAuthorization` (#38940 by @ClearlyClaire)

### Removed

- Remove unused devise strategies (#38795 by @ClearlyClaire)

## [4.5.9] - 2026-04-15

### Security

- Insufficient verification of email addresses ([GHSA-5r37-qpwq-2jhh](https://github.com/mastodon/mastodon/security/advisories/GHSA-5r37-qpwq-2jhh))
- Updated dependencies

### Added

- Add trademark warning to `mastodon:setup` task (#38548 by @ClearlyClaire)

### Fixed

- Fix definition for `quote` in JSON-LD context (#38686 by @ClearlyClaire)
- Fix being unable to disable sound for quote update notification (#38537 by @ClearlyClaire)
- Fix being able to quote someone you blocked (#38608 by @ClearlyClaire)

## [4.5.8] - 2026-03-24

### Security
Expand Down
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ GEM
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
uri (>= 0.13.1)
addressable (2.8.9)
addressable (2.9.0)
public_suffix (>= 2.0.2, < 8.0)
aes_key_wrap (1.1.0)
android_key_attestation (0.3.0)
Expand Down Expand Up @@ -190,7 +190,7 @@ GEM
irb (~> 1.10)
reline (>= 0.3.8)
debug_inspector (1.2.0)
devise (5.0.3)
devise (5.0.4)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 7.0)
Expand Down Expand Up @@ -472,7 +472,7 @@ GEM
net-smtp (0.5.1)
net-protocol
nio4r (2.7.5)
nokogiri (1.19.2)
nokogiri (1.19.3)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
omniauth (2.1.4)
Expand Down
6 changes: 3 additions & 3 deletions app/helpers/context_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ module ContextHelper
},
quote_authorizations: {
'gts' => 'https://gotosocial.org/ns#',
'quoteAuthorization' => { '@id' => 'https://w3id.org/fep/044f#quoteAuthorization', '@type' => '@id' },
'interactingObject' => { '@id' => 'gts:interactingObject' },
'interactionTarget' => { '@id' => 'gts:interactionTarget' },
'QuoteAuthorization' => 'https://w3id.org/fep/044f#QuoteAuthorization',
'interactingObject' => { '@id' => 'gts:interactingObject', '@type' => '@id' },
'interactionTarget' => { '@id' => 'gts:interactionTarget', '@type' => '@id' },
},
}.freeze

Expand Down
12 changes: 12 additions & 0 deletions app/helpers/json_ld_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
module JsonLdHelper
include ContextHelper

UNSUPPORTED_JSONLD_KEYWORDS = %w(@graph @included @reverse).freeze

def equals_or_includes?(haystack, needle)
haystack.is_a?(Array) ? haystack.include?(needle) : haystack == needle
end
Expand Down Expand Up @@ -118,6 +120,16 @@ def compact(json)
compacted
end

def unsupported_jsonld_features?(json)
if json.is_a?(Hash)
json.any? { |key, value| UNSUPPORTED_JSONLD_KEYWORDS.include?(key) || unsupported_jsonld_features?(value) }
elsif json.is_a?(Array)
json.any? { |value| unsupported_jsonld_features?(value) }
else
false
end
end

# Patches a JSON-LD document to avoid compatibility issues on redistribution
#
# Since compacting a JSON-LD document against Mastodon's built-in vocabulary
Expand Down
1 change: 1 addition & 0 deletions app/lib/activitypub/linked_data_signature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def initialize(json)

def verify_actor!
return unless @json['signature'].is_a?(Hash)
return if unsupported_jsonld_features?(@json)

type = @json['signature']['type']
creator_uri = @json['signature']['creator']
Expand Down
12 changes: 8 additions & 4 deletions app/lib/private_address_check.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# frozen_string_literal: true

module PrivateAddressCheck
IP4_CIDR_LIST = [
CIDR_LIST = [
# IPv4 addresses
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
Expand All @@ -14,23 +15,26 @@ 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) + [
# IPv6 addresses
IPAddr.new('::/128'), # Unspecified
IPAddr.new('64:ff9b::/96'), # IPv4/IPv6 translation (RFC 6052)
IPAddr.new('64:ff9b:1::/48'), # IPv4/IPv6 translation (RFC 8215)
IPAddr.new('100::/64'), # Discard prefix (RFC 6666)
IPAddr.new('2001::/32'), # Teredo tunneling
IPAddr.new('2001:10::/28'), # Deprecated (previously ORCHID)
IPAddr.new('2001:20::/28'), # ORCHIDv2
IPAddr.new('2001:db8::/32'), # Addresses used in documentation and example source code
IPAddr.new('2002::/16'), # 6to4
IPAddr.new('fc00::/7'), # Unique local address
IPAddr.new('3fff::/20'), # Addresses used in documentation and example source code
IPAddr.new('ff00::/8'), # Multicast
]).freeze
].freeze

module_function

def private_address?(address)
address = address.native if address.ipv6? && address.ipv4_mapped?
address.private? || address.loopback? || address.link_local? || CIDR_LIST.any? { |cidr| cidr.include?(address) }
end
end
4 changes: 4 additions & 0 deletions app/services/activitypub/process_collection_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ def call(body, actor, **options)

begin
@json = compact(@json) if @json['signature'].is_a?(Hash)
if unsupported_jsonld_features?(@json)
Rails.logger.debug { "JSON-LD document for #{value_or_id(@json['actor'])} contains unsupported JSON-LD features" }
@json = original_json.without('signature')
end
rescue JSON::LD::JsonLdError => e
Rails.logger.debug { "Error when compacting JSON-LD document for #{value_or_id(@json['actor'])}: #{e.message}" }
@json = original_json.without('signature')
Expand Down
2 changes: 0 additions & 2 deletions config/initializers/devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ def session_cookie
manager.default_strategies(scope: :user).unshift :two_factor_ldap_authenticatable if Devise.ldap_authentication
manager.default_strategies(scope: :user).unshift :two_factor_pam_authenticatable if Devise.pam_authentication
manager.default_strategies(scope: :user).unshift :session_activation_rememberable
manager.default_strategies(scope: :user).unshift :two_factor_authenticatable
manager.default_strategies(scope: :user).unshift :two_factor_backupable
end

# The secret key used by Devise. Devise uses this key to generate
Expand Down
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: kmyblue:23.1
image: kmyblue:23.2
restart: always
env_file: .env.production
command: bundle exec puma -C config/puma.rb
Expand All @@ -83,7 +83,7 @@ services:
build:
dockerfile: ./streaming/Dockerfile
context: .
image: kmyblue-streaming:23.1
image: kmyblue-streaming:23.2
restart: always
env_file: .env.production
command: node ./streaming/index.js
Expand All @@ -101,7 +101,7 @@ services:

sidekiq:
build: .
image: kmyblue:23.1
image: kmyblue:23.2
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 kmyblue_major
end

def kmyblue_minor
1
2
end

def kmyblue_flag
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5807,13 +5807,13 @@ __metadata:
linkType: hard

"axios@npm:^1.15.0":
version: 1.15.0
resolution: "axios@npm:1.15.0"
version: 1.15.2
resolution: "axios@npm:1.15.2"
dependencies:
follow-redirects: "npm:^1.15.11"
form-data: "npm:^4.0.5"
proxy-from-env: "npm:^2.1.0"
checksum: 10c0/47e0f860e98d4d7aa145e89ce0cae00e1fb0f1d2485f065c21fce955ddb1dba4103a46bd0e47acd18a27208a7f62c96249e620db575521b92a968619ab133409
checksum: 10c0/4eeae0feeaa7fdc1ef24f81f8b378fdadedf4aebdd6bf224484675160f8744cf17b9b0d1c215279979940f7e8ce463beffa2f713099612e428eac238515c81d5
languageName: node
linkType: hard

Expand Down
Loading