From d8abc0018f59ed63fb6c5fae2f6081c141a4b978 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 26 May 2022 18:43:14 +0200 Subject: [PATCH 01/10] Remove 3.3.x from supported versions in security policy (#18516) --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 12f50ed88..62e23f736 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -14,7 +14,7 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through | ------- | ------------------ | | 3.5.x | Yes | | 3.4.x | Yes | -| 3.3.x | Yes | +| 3.3.x | No | | < 3.3 | No | [bug-bounty]: https://app.intigriti.com/programs/mastodon/mastodonio/detail From 702b709d9a8df2ed65c54d32d585a4cf5fe13de1 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Fri, 27 May 2022 03:29:28 +0900 Subject: [PATCH 02/10] Add ES6 compatibility to browserslist (#18519) --- .browserslistrc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.browserslistrc b/.browserslistrc index d5734664c..54dd3aaf3 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -4,6 +4,4 @@ not IE 11 not dead [development] -last 1 chrome version -last 1 firefox version -last 1 safari version +supports es6-module From 3e0e7a1cfb617837ccada330afc13ed804c3c47b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 26 May 2022 20:32:48 +0200 Subject: [PATCH 03/10] Fix follower and other counters being able to go negative (#18517) --- app/models/account_stat.rb | 12 ++++++++++++ app/models/status_stat.rb | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/app/models/account_stat.rb b/app/models/account_stat.rb index b49827267..a5d71a5b8 100644 --- a/app/models/account_stat.rb +++ b/app/models/account_stat.rb @@ -20,4 +20,16 @@ class AccountStat < ApplicationRecord belongs_to :account, inverse_of: :account_stat update_index('accounts', :account) + + def following_count + [attributes['following_count'], 0].max + end + + def followers_count + [attributes['followers_count'], 0].max + end + + def statuses_count + [attributes['statuses_count'], 0].max + end end diff --git a/app/models/status_stat.rb b/app/models/status_stat.rb index 024c467e7..437861d1c 100644 --- a/app/models/status_stat.rb +++ b/app/models/status_stat.rb @@ -17,6 +17,18 @@ class StatusStat < ApplicationRecord after_commit :reset_parent_cache + def replies_count + [attributes['replies_count'], 0].max + end + + def reblogs_count + [attributes['reblogs_count'], 0].max + end + + def favourites_count + [attributes['favourites_count'], 0].max + end + private def reset_parent_cache From 96129c2f10a82520648f6ae04e585cf797403617 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 26 May 2022 22:03:54 +0200 Subject: [PATCH 04/10] Fix confirmation redirect to app without `Location` header (#18523) --- app/controllers/auth/confirmations_controller.rb | 2 +- app/lib/application_extension.rb | 4 ++++ config/initializers/doorkeeper.rb | 7 +++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/controllers/auth/confirmations_controller.rb b/app/controllers/auth/confirmations_controller.rb index 1475bbcef..010fd3755 100644 --- a/app/controllers/auth/confirmations_controller.rb +++ b/app/controllers/auth/confirmations_controller.rb @@ -40,7 +40,7 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController def after_confirmation_path_for(_resource_name, user) if user.created_by_application && truthy_param?(:redirect_to_app) - user.created_by_application.redirect_uri + user.created_by_application.confirmation_redirect_uri else super end diff --git a/app/lib/application_extension.rb b/app/lib/application_extension.rb index a1fea6430..d61ec0e6e 100644 --- a/app/lib/application_extension.rb +++ b/app/lib/application_extension.rb @@ -12,4 +12,8 @@ module ApplicationExtension def most_recently_used_access_token @most_recently_used_access_token ||= access_tokens.where.not(last_used_at: nil).order(last_used_at: :desc).first end + + def confirmation_redirect_uri + redirect_uri.lines.first.strip + end end diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb index f78db8653..84b649f5c 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -128,6 +128,13 @@ Doorkeeper.configure do # force_ssl_in_redirect_uri false + # Specify what redirect URI's you want to block during Application creation. + # Any redirect URI is whitelisted by default. + # + # You can use this option in order to forbid URI's with 'javascript' scheme + # for example. + forbid_redirect_uri { |uri| %w[data vbscript javascript].include?(uri.scheme.to_s.downcase) } + # Specify what grant flows are enabled in array of Strings. The valid # strings and the flows they enable are: # From 9f81b9f29a14093cefcdbf09058ace089cd8e06b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 26 May 2022 22:04:05 +0200 Subject: [PATCH 05/10] Fix suspended users being able to access APIs that don't require a user (#18524) --- app/controllers/activitypub/base_controller.rb | 1 + app/controllers/api/base_controller.rb | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/app/controllers/activitypub/base_controller.rb b/app/controllers/activitypub/base_controller.rb index 196d85a32..b8a7e0ab9 100644 --- a/app/controllers/activitypub/base_controller.rb +++ b/app/controllers/activitypub/base_controller.rb @@ -2,6 +2,7 @@ class ActivityPub::BaseController < Api::BaseController skip_before_action :require_authenticated_user! + skip_before_action :require_not_suspended! skip_around_action :set_locale private diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index d96285b44..2e393fbb6 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -11,6 +11,7 @@ class Api::BaseController < ApplicationController skip_before_action :require_functional!, unless: :whitelist_mode? before_action :require_authenticated_user!, if: :disallow_unauthenticated_api_access? + before_action :require_not_suspended! before_action :set_cache_headers protect_from_forgery with: :null_session @@ -97,6 +98,10 @@ class Api::BaseController < ApplicationController render json: { error: 'This method requires an authenticated user' }, status: 401 unless current_user end + def require_not_suspended! + render json: { error: 'Your login is currently disabled' }, status: 403 if current_user&.account&.suspended? + end + def require_user! if !current_user render json: { error: 'This method requires an authenticated user' }, status: 422 From 976cd6413e9b2a1531a2ad17945342deaeec538c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 26 May 2022 22:04:16 +0200 Subject: [PATCH 06/10] Fix moderator leak in undo_mark_statuses_as_sensitive (#18525) Signed-off-by: Eugen Rochko Co-authored-by: 40826d <74816220+40826d@users.noreply.github.com> --- app/services/approve_appeal_service.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/services/approve_appeal_service.rb b/app/services/approve_appeal_service.rb index 37a08b46e..96aaaa7d0 100644 --- a/app/services/approve_appeal_service.rb +++ b/app/services/approve_appeal_service.rb @@ -52,8 +52,9 @@ class ApproveAppealService < BaseService end def undo_mark_statuses_as_sensitive! + representative_account = Account.representative @strike.statuses.includes(:media_attachments).each do |status| - UpdateStatusService.new.call(status, @current_account.id, sensitive: false) if status.with_media? + UpdateStatusService.new.call(status, representative_account.id, sensitive: false) if status.with_media? end end From 1ff4877945e18820f3e518a1cfbac243da65e1a5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 26 May 2022 22:06:10 +0200 Subject: [PATCH 07/10] Fix empty votes arbitrarily increasing voters count in polls (#18526) --- app/services/vote_service.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/services/vote_service.rb b/app/services/vote_service.rb index ccd04dbfc..114ec285c 100644 --- a/app/services/vote_service.rb +++ b/app/services/vote_service.rb @@ -7,6 +7,8 @@ class VoteService < BaseService include Lockable def call(account, poll, choices) + return if choices.empty? + authorize_with account, poll, :vote? @account = account From c4d2c39a75eccdbc60c3540c259e1e7ea5881ac6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 26 May 2022 22:08:02 +0200 Subject: [PATCH 08/10] Fix being able to report otherwise inaccessible statuses (#18528) --- app/models/admin/status_batch_action.rb | 6 +++++- app/services/report_service.rb | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/models/admin/status_batch_action.rb b/app/models/admin/status_batch_action.rb index 631af183c..7bf6fa6da 100644 --- a/app/models/admin/status_batch_action.rb +++ b/app/models/admin/status_batch_action.rb @@ -103,7 +103,7 @@ class Admin::StatusBatchAction def handle_report! @report = Report.new(report_params) unless with_report? - @report.status_ids = (@report.status_ids + status_ids.map(&:to_i)).uniq + @report.status_ids = (@report.status_ids + allowed_status_ids).uniq @report.save! @report_id = @report.id @@ -135,4 +135,8 @@ class Admin::StatusBatchAction def report_params { account: current_account, target_account: target_account } end + + def allowed_status_ids + AccountStatusesFilter.new(@report.target_account, current_account).results.with_discarded.where(id: status_ids).pluck(:id) + end end diff --git a/app/services/report_service.rb b/app/services/report_service.rb index 9d784c341..d251bb33f 100644 --- a/app/services/report_service.rb +++ b/app/services/report_service.rb @@ -57,7 +57,7 @@ class ReportService < BaseService end def reported_status_ids - @target_account.statuses.with_discarded.find(Array(@status_ids)).pluck(:id) + AccountStatusesFilter.new(@target_account, @source_account).results.with_discarded.find(Array(@status_ids)).pluck(:id) end def payload From 8a9acbe604667215c9589154d72b3f313755c210 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 26 May 2022 22:08:12 +0200 Subject: [PATCH 09/10] Fix being able to appeal a strike unlimited times (#18529) Peculiarity of the `has_one` association is that the convenience creation method deletes the previous association even if the new one is invalid --- app/services/appeal_service.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/services/appeal_service.rb b/app/services/appeal_service.rb index 1397c50f5..cef9be05f 100644 --- a/app/services/appeal_service.rb +++ b/app/services/appeal_service.rb @@ -14,7 +14,8 @@ class AppealService < BaseService private def create_appeal! - @appeal = @strike.create_appeal!( + @appeal = Appeal.create!( + strike: @strike, text: @text, account: @strike.target_account ) From 52f4e834f293c9fdbf5805639d022ac4e3856b75 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 26 May 2022 22:14:47 +0200 Subject: [PATCH 10/10] Fix concurrent unfollowing decrementing follower count more than once (#18527) --- app/services/unfollow_service.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/services/unfollow_service.rb b/app/services/unfollow_service.rb index 151f3674f..d83a60e4e 100644 --- a/app/services/unfollow_service.rb +++ b/app/services/unfollow_service.rb @@ -2,6 +2,8 @@ class UnfollowService < BaseService include Payloadable + include Redisable + include Lockable # Unfollow and notify the remote user # @param [Account] source_account Where to unfollow from @@ -13,7 +15,9 @@ class UnfollowService < BaseService @target_account = target_account @options = options - unfollow! || undo_follow_request! + with_lock("relationship:#{[source_account.id, target_account.id].sort.join(':')}") do + unfollow! || undo_follow_request! + end end private