From 038d3b15135eb66e6e68bf236b8f76bdfe162235 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 25 Apr 2025 11:00:54 +0200 Subject: [PATCH 1/9] Fix sign-up e-mail confirmation page reloading on error or redirect (#34548) --- app/javascript/entrypoints/sign_up.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/javascript/entrypoints/sign_up.ts b/app/javascript/entrypoints/sign_up.ts index 880738fcb7..87100be56d 100644 --- a/app/javascript/entrypoints/sign_up.ts +++ b/app/javascript/entrypoints/sign_up.ts @@ -4,9 +4,12 @@ import axios from 'axios'; import ready from '../mastodon/ready'; async function checkConfirmation() { - const response = await axios.get('/api/v1/emails/check_confirmation'); + const response = await axios.get('/api/v1/emails/check_confirmation', { + headers: { Accept: 'application/json' }, + withCredentials: true, + }); - if (response.data) { + if (response.status === 200 && response.data === true) { window.location.href = '/start'; } } From 843a5446e841fc9191a887d3e51147142dfdee57 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 25 Apr 2025 13:24:57 +0200 Subject: [PATCH 2/9] Fix incorrect redirect in response to unauthenticated API requests in limited federation mode (#34549) --- app/controllers/api/base_controller.rb | 7 +++++++ app/controllers/application_controller.rb | 22 ++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index 06a113511c..b73dae17e5 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -72,6 +72,13 @@ class Api::BaseController < ApplicationController end end + # Redefine `require_functional!` to properly output JSON instead of HTML redirects + def require_functional! + return if current_user.functional? + + require_user! + end + def render_empty render json: {}, status: 200 end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1b071e8655..c11fd2a635 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -72,10 +72,24 @@ class ApplicationController < ActionController::Base def require_functional! return if current_user.functional? - if current_user.confirmed? - redirect_to edit_user_registration_path - else - redirect_to auth_setup_path + respond_to do |format| + format.any do + if current_user.confirmed? + redirect_to edit_user_registration_path + else + redirect_to auth_setup_path + end + end + + format.json do + if !current_user.confirmed? + render json: { error: 'Your login is missing a confirmed e-mail address' }, status: 403 + elsif !current_user.approved? + render json: { error: 'Your login is currently pending approval' }, status: 403 + elsif !current_user.functional? + render json: { error: 'Your login is currently disabled' }, status: 403 + end + end end end From a7bc2885697b53e3e6c8c67f845436bc5a343cff Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 29 Apr 2025 10:51:03 +0200 Subject: [PATCH 3/9] Add built-in context for interaction policies (#34574) --- app/helpers/context_helper.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/helpers/context_helper.rb b/app/helpers/context_helper.rb index 077c5272a5..79080895a4 100644 --- a/app/helpers/context_helper.rb +++ b/app/helpers/context_helper.rb @@ -35,6 +35,13 @@ module ContextHelper suspended: { 'toot' => 'http://joinmastodon.org/ns#', 'suspended' => 'toot:suspended' }, attribution_domains: { 'toot' => 'http://joinmastodon.org/ns#', 'attributionDomains' => { '@id' => 'toot:attributionDomains', '@type' => '@id' } }, misskey_license: { 'misskey' => 'https://misskey-hub.net/ns#', '_misskey_license' => 'misskey:_misskey_license' }, + interaction_policies: { + 'gts' => 'https://gotosocial.org/ns#', + 'interactionPolicy' => { '@id' => 'gts:interactionPolicy', '@type' => '@id' }, + 'canQuote' => { '@id' => 'gts:canQuote', '@type' => '@id' }, + 'automaticApproval' => { '@id' => 'gts:automaticApproval', '@type' => '@id' }, + 'manualApproval' => { '@id' => 'gts:manualApproval', '@type' => '@id' }, + }, }.freeze def full_context From f41c09f291c1981239c7673923e136dbe82fff00 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 5 May 2025 14:33:31 +0200 Subject: [PATCH 4/9] Remove double-query for signed query strings (#34610) --- app/lib/http_signature_draft.rb | 5 ++--- app/lib/request.rb | 3 +-- app/services/activitypub/fetch_replies_service.rb | 15 +-------------- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/app/lib/http_signature_draft.rb b/app/lib/http_signature_draft.rb index fc0d498b29..cb794b223a 100644 --- a/app/lib/http_signature_draft.rb +++ b/app/lib/http_signature_draft.rb @@ -6,14 +6,13 @@ class HttpSignatureDraft REQUEST_TARGET = '(request-target)' - def initialize(keypair, key_id, full_path: true) + def initialize(keypair, key_id) @keypair = keypair @key_id = key_id - @full_path = full_path end def request_target(verb, url) - if url.query.nil? || !@full_path + if url.query.nil? "#{verb} #{url.path}" else "#{verb} #{url.path}?#{url.query}" diff --git a/app/lib/request.rb b/app/lib/request.rb index ad39f928db..212acf64d0 100644 --- a/app/lib/request.rb +++ b/app/lib/request.rb @@ -75,7 +75,6 @@ class Request @url = Addressable::URI.parse(url).normalize @http_client = options.delete(:http_client) @allow_local = options.delete(:allow_local) - @full_path = !options.delete(:omit_query_string) @options = { follow: { max_hops: 3, @@ -102,7 +101,7 @@ class Request key_id = ActivityPub::TagManager.instance.key_uri_for(actor) keypair = sign_with.present? ? OpenSSL::PKey::RSA.new(sign_with) : actor.keypair - @signing = HttpSignatureDraft.new(keypair, key_id, full_path: @full_path) + @signing = HttpSignatureDraft.new(keypair, key_id) self end diff --git a/app/services/activitypub/fetch_replies_service.rb b/app/services/activitypub/fetch_replies_service.rb index f2e4f45104..6a6d9e391a 100644 --- a/app/services/activitypub/fetch_replies_service.rb +++ b/app/services/activitypub/fetch_replies_service.rb @@ -57,20 +57,7 @@ class ActivityPub::FetchRepliesService < BaseService return unless @allow_synchronous_requests return if non_matching_uri_hosts?(@reference_uri, collection_or_uri) - # NOTE: For backward compatibility reasons, Mastodon signs outgoing - # queries incorrectly by default. - # - # While this is relevant for all URLs with query strings, this is - # the only code path where this happens in practice. - # - # Therefore, retry with correct signatures if this fails. - begin - fetch_resource_without_id_validation(collection_or_uri, nil, raise_on_error: :temporary) - 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, raise_on_error: :temporary, request_options: { omit_query_string: false }) - end + fetch_resource_without_id_validation(collection_or_uri, nil, raise_on_error: :temporary) end def filter_replies(items) From ff90575e2c6e790b99423944779d7512048bd7b5 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 5 May 2025 15:01:16 +0200 Subject: [PATCH 5/9] Add warning for REDIS_NAMESPACE deprecation at startup (#34581) --- config/initializers/deprecations.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 config/initializers/deprecations.rb diff --git a/config/initializers/deprecations.rb b/config/initializers/deprecations.rb new file mode 100644 index 0000000000..e0ad54d8c3 --- /dev/null +++ b/config/initializers/deprecations.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +if ENV['REDIS_NAMESPACE'] + es_configured = ENV['ES_ENABLED'] == 'true' || ENV.fetch('ES_HOST', 'localhost') != 'localhost' || ENV.fetch('ES_PORT', '9200') != '9200' || ENV.fetch('ES_PASS', 'password') != 'password' + + warn <<~MESSAGE + WARNING: the REDIS_NAMESPACE environment variable is deprecated and will be removed in Mastodon 4.4.0. + + Please see documentation at https://github.com/mastodon/redis_namespace_migration + MESSAGE + + warn <<~MESSAGE if es_configured && !ENV['ES_PREFIX'] + + In addition, as REDIS_NAMESPACE is being used as a prefix for Elasticsearch, please do not forget to set ES_PREFIX to "#{ENV.fetch('REDIS_NAMESPACE')}". + MESSAGE +end From d510b5d8b92cd46b6c98446b08627290d8e3676d Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 6 May 2025 15:02:13 +0200 Subject: [PATCH 6/9] Merge commit from fork * Check scheme in account and post links * Harden media attachments * Client-side mitigation * Client-side mitigation for media attachments --- .../mastodon/actions/importer/normalizer.js | 11 +++++++++++ app/javascript/mastodon/models/account.ts | 1 + app/lib/activitypub/parser/media_attachment_parser.rb | 6 ++++-- app/lib/activitypub/parser/status_parser.rb | 5 ++++- app/lib/activitypub/tag_manager.rb | 3 ++- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js index b643cf5613..ff2e10c79d 100644 --- a/app/javascript/mastodon/actions/importer/normalizer.js +++ b/app/javascript/mastodon/actions/importer/normalizer.js @@ -94,6 +94,17 @@ export function normalizeStatus(status, normalOldStatus) { normalStatus.contentHtml = emojify(normalStatus.content, emojiMap); normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(spoilerText), emojiMap); normalStatus.hidden = expandSpoilers ? false : spoilerText.length > 0 || normalStatus.sensitive; + + if (normalStatus.url && !(normalStatus.url.startsWith('http://') || normalStatus.url.startsWith('https://'))) { + normalStatus.url = null; + } + + normalStatus.url ||= normalStatus.uri; + + normalStatus.media_attachments.forEach(item => { + if (item.remote_url && !(item.remote_url.startsWith('http://') || item.remote_url.startsWith('https://'))) + item.remote_url = null; + }); } if (normalOldStatus) { diff --git a/app/javascript/mastodon/models/account.ts b/app/javascript/mastodon/models/account.ts index 55dbbcbb34..43f134f03d 100644 --- a/app/javascript/mastodon/models/account.ts +++ b/app/javascript/mastodon/models/account.ts @@ -178,5 +178,6 @@ export function createAccountFromServerJSON(serverJSON: ApiAccountJSON) { ), note_emojified: emojify(accountJSON.note, emojiMap), note_plain: unescapeHTML(accountJSON.note), + url: accountJSON.url.startsWith('http://') || accountJSON.url.startsWith('https://') ? accountJSON.url : accountJSON.uri, }); } diff --git a/app/lib/activitypub/parser/media_attachment_parser.rb b/app/lib/activitypub/parser/media_attachment_parser.rb index 56b8b23f84..bcbf92214f 100644 --- a/app/lib/activitypub/parser/media_attachment_parser.rb +++ b/app/lib/activitypub/parser/media_attachment_parser.rb @@ -15,13 +15,15 @@ class ActivityPub::Parser::MediaAttachmentParser end def remote_url - Addressable::URI.parse(@json['url'])&.normalize&.to_s + url = Addressable::URI.parse(@json['url'])&.normalize&.to_s + url unless unsupported_uri_scheme?(url) rescue Addressable::URI::InvalidURIError nil end def thumbnail_remote_url - Addressable::URI.parse(@json['icon'].is_a?(Hash) ? @json['icon']['url'] : @json['icon'])&.normalize&.to_s + url = Addressable::URI.parse(@json['icon'].is_a?(Hash) ? @json['icon']['url'] : @json['icon'])&.normalize&.to_s + url unless unsupported_uri_scheme?(url) rescue Addressable::URI::InvalidURIError nil end diff --git a/app/lib/activitypub/parser/status_parser.rb b/app/lib/activitypub/parser/status_parser.rb index 1968f18468..03e3f789b5 100644 --- a/app/lib/activitypub/parser/status_parser.rb +++ b/app/lib/activitypub/parser/status_parser.rb @@ -33,7 +33,10 @@ class ActivityPub::Parser::StatusParser end def url - url_to_href(@object['url'], 'text/html') if @object['url'].present? + return if @object['url'].blank? + + url = url_to_href(@object['url'], 'text/html') + url unless unsupported_uri_scheme?(url) end def text diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index 3ead162ec3..99d85a262a 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -4,6 +4,7 @@ require 'singleton' class ActivityPub::TagManager include Singleton + include JsonLdHelper include RoutingHelper CONTEXT = 'https://www.w3.org/ns/activitystreams' @@ -17,7 +18,7 @@ class ActivityPub::TagManager end def url_for(target) - return target.url if target.respond_to?(:local?) && !target.local? + return unsupported_uri_scheme?(target.url) ? nil : target.url if target.respond_to?(:local?) && !target.local? return unless target.respond_to?(:object_type) From d21a4f8c3920f56fa70da9bbdb13511408655124 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 6 May 2025 15:35:54 +0200 Subject: [PATCH 7/9] Fix code style issue (#34624) --- app/javascript/mastodon/models/account.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/models/account.ts b/app/javascript/mastodon/models/account.ts index 43f134f03d..88cbc3359b 100644 --- a/app/javascript/mastodon/models/account.ts +++ b/app/javascript/mastodon/models/account.ts @@ -178,6 +178,10 @@ export function createAccountFromServerJSON(serverJSON: ApiAccountJSON) { ), note_emojified: emojify(accountJSON.note, emojiMap), note_plain: unescapeHTML(accountJSON.note), - url: accountJSON.url.startsWith('http://') || accountJSON.url.startsWith('https://') ? accountJSON.url : accountJSON.uri, + url: + accountJSON.url.startsWith('http://') || + accountJSON.url.startsWith('https://') + ? accountJSON.url + : accountJSON.uri, }); } From 95244879095aa3303379444b8f1ca360963a9c52 Mon Sep 17 00:00:00 2001 From: KMY Date: Wed, 7 May 2025 08:00:56 +0900 Subject: [PATCH 8/9] Bump version to v4.3.8 (#34626) --- CHANGELOG.md | 48 +++++++++++++++++++++++++++++++++++++++++ Gemfile.lock | 2 +- docker-compose.yml | 6 +++--- lib/mastodon/version.rb | 4 ++-- 4 files changed, 54 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7b0f64146..a9819a6c79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,54 @@ All notable changes to this project will be documented in this file. +## [4.3.8] - 2025-05-06 + +### Security + +- Update dependencies +- Check scheme on account, profile, and media URLs ([GHSA-x2rc-v5wx-g3m5](https://github.com/mastodon/mastodon/security/advisories/GHSA-x2rc-v5wx-g3m5)) + +### Added + +- Add warning for REDIS_NAMESPACE deprecation at startup (#34581 by @ClearlyClaire) +- Add built-in context for interaction policies (#34574 by @ClearlyClaire) + +### Changed + +- Change activity distribution error handling to skip retrying for deleted accounts (#33617 by @ClearlyClaire) + +### Removed + +- Remove double-query for signed query strings (#34610 by @ClearlyClaire) + +### Fixed + +- Fix incorrect redirect in response to unauthenticated API requests in limited federation mode (#34549 by @ClearlyClaire) +- Fix sign-up e-mail confirmation page reloading on error or redirect (#34548 by @ClearlyClaire) + +## [4.3.7] - 2025-04-02 + +### Added + +- Add delay to profile updates to debounce them (#34137 by @ClearlyClaire) +- Add support for paginating partial collections in `SynchronizeFollowersService` (#34272 and #34277 by @ClearlyClaire) + +### Changed + +- Change account suspensions to be federated to recently-followed accounts as well (#34294 by @ClearlyClaire) +- Change `AccountReachFinder` to consider statuses based on suspension date (#32805 and #34291 by @ClearlyClaire and @mjankowski) +- Change user archive signed URL TTL from 10 seconds to 1 hour (#34254 by @ClearlyClaire) + +### Fixed + +- Fix static version of animated PNG emojis not being properly extracted (#34337 by @ClearlyClaire) +- Fix filters not applying in detailed view, favourites and bookmarks (#34259 and #34260 by @ClearlyClaire) +- Fix handling of malformed/unusual HTML (#34201 by @ClearlyClaire) +- Fix `CacheBuster` being queued for missing media attachments (#34253 by @ClearlyClaire) +- Fix incorrect URL being used when cache busting (#34189 by @ClearlyClaire) +- Fix streaming server refusing unix socket path in `DATABASE_URL` (#34091 by @ClearlyClaire) +- Fix “x” hotkey not working on boosted filtered posts (#33758 by @ClearlyClaire) + ## [4.3.6] - 2025-03-13 ### Security diff --git a/Gemfile.lock b/Gemfile.lock index 80049a7dc2..fdb5c12ed8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -446,7 +446,7 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.4) - nokogiri (1.18.7) + nokogiri (1.18.8) mini_portile2 (~> 2.8.2) racc (~> 1.4) oj (3.16.10) diff --git a/docker-compose.yml b/docker-compose.yml index cc9254b21f..b88ea761dc 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: kmyblue:18.0 + image: kmyblue:18.1 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: kmyblue-streaming:18.0 + image: kmyblue-streaming:18.1 restart: always env_file: .env.production command: node ./streaming/index.js @@ -101,7 +101,7 @@ services: sidekiq: build: . - image: kmyblue:18.0 + image: kmyblue:18.1 restart: always env_file: .env.production command: bundle exec sidekiq diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 41887dfb31..e8eca96a71 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -13,7 +13,7 @@ module Mastodon end def kmyblue_minor - 0 + 1 end def kmyblue_flag @@ -35,7 +35,7 @@ module Mastodon end def default_prerelease - 'alpha.4' + 'alpha.5' end def prerelease From 49e05d9f2bc6be2744880699876ca0afe9d8e9b4 Mon Sep 17 00:00:00 2001 From: KMY Date: Wed, 7 May 2025 11:27:14 +0900 Subject: [PATCH 9/9] Fix test --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index fdb5c12ed8..0fb210eaa4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -435,7 +435,7 @@ GEM mutex_m (0.3.0) net-http (0.6.0) uri - net-imap (0.5.6) + net-imap (0.5.7) date net-protocol net-ldap (0.19.0)