commit
9a0f85f00c
13 changed files with 42 additions and 23 deletions
10
.bundler-audit.yml
Normal file
10
.bundler-audit.yml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
ignore:
|
||||||
|
# devise-two-factor advisory about brute-forcing TOTP
|
||||||
|
# We have rate-limits on authentication endpoints in place (including second
|
||||||
|
# factor verification) since Mastodon v3.2.0
|
||||||
|
- CVE-2024-0227
|
||||||
|
# devise-two-factor advisory about generated secrets being weaker than expected
|
||||||
|
# We call `generate_otp_secret` ourselves with a requested length of 32 characters,
|
||||||
|
# which exceeds the recommended remediation of 26 characters, so we're safe
|
||||||
|
- CVE-2024-8796
|
10
Gemfile.lock
10
Gemfile.lock
|
@ -290,8 +290,10 @@ GEM
|
||||||
ruby-progressbar (~> 1.4)
|
ruby-progressbar (~> 1.4)
|
||||||
globalid (1.2.1)
|
globalid (1.2.1)
|
||||||
activesupport (>= 6.1)
|
activesupport (>= 6.1)
|
||||||
google-protobuf (3.25.4)
|
google-protobuf (4.28.2)
|
||||||
googleapis-common-protos-types (1.15.0)
|
bigdecimal
|
||||||
|
rake (>= 13)
|
||||||
|
googleapis-common-protos-types (1.16.0)
|
||||||
google-protobuf (>= 3.18, < 5.a)
|
google-protobuf (>= 3.18, < 5.a)
|
||||||
haml (6.3.0)
|
haml (6.3.0)
|
||||||
temple (>= 0.8.2)
|
temple (>= 0.8.2)
|
||||||
|
@ -607,7 +609,7 @@ GEM
|
||||||
psych (5.1.2)
|
psych (5.1.2)
|
||||||
stringio
|
stringio
|
||||||
public_suffix (6.0.1)
|
public_suffix (6.0.1)
|
||||||
puma (6.4.2)
|
puma (6.4.3)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
pundit (2.4.0)
|
pundit (2.4.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
|
@ -892,7 +894,7 @@ GEM
|
||||||
rack-proxy (>= 0.6.1)
|
rack-proxy (>= 0.6.1)
|
||||||
railties (>= 5.2)
|
railties (>= 5.2)
|
||||||
semantic_range (>= 2.3.0)
|
semantic_range (>= 2.3.0)
|
||||||
webrick (1.8.1)
|
webrick (1.8.2)
|
||||||
websocket (1.2.11)
|
websocket (1.2.11)
|
||||||
websocket-driver (0.7.6)
|
websocket-driver (0.7.6)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
|
|
|
@ -12,7 +12,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
|
||||||
before_action :set_replies
|
before_action :set_replies
|
||||||
|
|
||||||
def index
|
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
|
render json: replies_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', skip_activities: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ class ActivityPub::LinkedDataSignature
|
||||||
include JsonLdHelper
|
include JsonLdHelper
|
||||||
|
|
||||||
CONTEXT = 'https://w3id.org/identity/v1'
|
CONTEXT = 'https://w3id.org/identity/v1'
|
||||||
|
SIGNATURE_CONTEXT = 'https://w3id.org/security/v1'
|
||||||
|
|
||||||
def initialize(json)
|
def initialize(json)
|
||||||
@json = json.with_indifferent_access
|
@json = json.with_indifferent_access
|
||||||
|
@ -46,7 +47,13 @@ class ActivityPub::LinkedDataSignature
|
||||||
|
|
||||||
signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), to_be_signed))
|
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
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -14,14 +14,16 @@ class Admin::SystemCheck::SoftwareVersionCheck < Admin::SystemCheck::BaseCheck
|
||||||
def message
|
def message
|
||||||
if software_updates.any?(&:urgent?)
|
if software_updates.any?(&:urgent?)
|
||||||
Admin::SystemCheck::Message.new(:software_version_critical_check, nil, admin_software_updates_path, true)
|
Admin::SystemCheck::Message.new(:software_version_critical_check, nil, admin_software_updates_path, true)
|
||||||
else
|
elsif software_updates.any?(&:patch_type?)
|
||||||
Admin::SystemCheck::Message.new(:software_version_patch_check, nil, admin_software_updates_path)
|
Admin::SystemCheck::Message.new(:software_version_patch_check, nil, admin_software_updates_path)
|
||||||
|
else
|
||||||
|
Admin::SystemCheck::Message.new(:software_version_check, nil, admin_software_updates_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def software_updates
|
def software_updates
|
||||||
@software_updates ||= SoftwareUpdate.pending_to_a.filter { |update| update.urgent? || update.patch_type? }
|
@software_updates ||= SoftwareUpdate.pending_to_a
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -598,7 +598,7 @@ class FeedManager
|
||||||
arr = crutches[:active_mentions][s.id] || []
|
arr = crutches[:active_mentions][s.id] || []
|
||||||
arr.push(s.account_id)
|
arr.push(s.account_id)
|
||||||
|
|
||||||
if s.reblog?
|
if s.reblog? && s.reblog.present?
|
||||||
arr.push(s.reblog.account_id)
|
arr.push(s.reblog.account_id)
|
||||||
arr.concat(crutches[:active_mentions][s.reblog_of_id] || [])
|
arr.concat(crutches[:active_mentions][s.reblog_of_id] || [])
|
||||||
end
|
end
|
||||||
|
|
|
@ -77,7 +77,7 @@ class Request
|
||||||
@url = Addressable::URI.parse(url).normalize
|
@url = Addressable::URI.parse(url).normalize
|
||||||
@http_client = options.delete(:http_client)
|
@http_client = options.delete(:http_client)
|
||||||
@allow_local = options.delete(:allow_local)
|
@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(socket_class: use_proxy? || @allow_local ? ProxySocket : Socket)
|
||||||
@options = @options.merge(timeout_class: PerOperationWithDeadline, timeout_options: TIMEOUT)
|
@options = @options.merge(timeout_class: PerOperationWithDeadline, timeout_options: TIMEOUT)
|
||||||
@options = @options.merge(proxy_url) if use_proxy?
|
@options = @options.merge(proxy_url) if use_proxy?
|
||||||
|
|
|
@ -71,8 +71,8 @@ class Account < ApplicationRecord
|
||||||
DEFAULT_FIELDS_SIZE = 6
|
DEFAULT_FIELDS_SIZE = 6
|
||||||
INSTANCE_ACTOR_ID = -99
|
INSTANCE_ACTOR_ID = -99
|
||||||
|
|
||||||
USERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i
|
USERNAME_RE = /[a-z0-9_]+([.-]+[a-z0-9_]+)*/i
|
||||||
MENTION_RE = %r{(?<![=/[:word:]])@((#{USERNAME_RE})(?:@[[:word:].-]+[[:word:]]+)?)}
|
MENTION_RE = %r{(?<![=/[:word:]])@((#{USERNAME_RE})(?:@[[:word:]]+([.-]+[[:word:]]+)*)?)}
|
||||||
URL_PREFIX_RE = %r{\Ahttp(s?)://[^/]+}
|
URL_PREFIX_RE = %r{\Ahttp(s?)://[^/]+}
|
||||||
USERNAME_ONLY_RE = /\A#{USERNAME_RE}\z/i
|
USERNAME_ONLY_RE = /\A#{USERNAME_RE}\z/i
|
||||||
USERNAME_LENGTH_LIMIT = 30
|
USERNAME_LENGTH_LIMIT = 30
|
||||||
|
|
|
@ -49,7 +49,7 @@ class ActivityPub::FetchRepliesService < BaseService
|
||||||
rescue Mastodon::UnexpectedResponseError => e
|
rescue Mastodon::UnexpectedResponseError => e
|
||||||
raise unless e.response && e.response.code == 401 && Addressable::URI.parse(collection_or_uri).query.present?
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1136,6 +1136,9 @@ en:
|
||||||
message_html: You haven't defined any server rules.
|
message_html: You haven't defined any server rules.
|
||||||
sidekiq_process_check:
|
sidekiq_process_check:
|
||||||
message_html: No Sidekiq process running for the %{value} queue(s). Please review your Sidekiq configuration
|
message_html: No Sidekiq process running for the %{value} queue(s). Please review your Sidekiq configuration
|
||||||
|
software_version_check:
|
||||||
|
action: See available updates
|
||||||
|
message_html: A Mastodon update is available.
|
||||||
software_version_critical_check:
|
software_version_critical_check:
|
||||||
action: See available updates
|
action: See available updates
|
||||||
message_html: A critical Mastodon update is available, please update as quickly as possible.
|
message_html: A critical Mastodon update is available, please update as quickly as possible.
|
||||||
|
|
|
@ -9,7 +9,7 @@ module Mastodon
|
||||||
end
|
end
|
||||||
|
|
||||||
def kmyblue_minor
|
def kmyblue_minor
|
||||||
1
|
2
|
||||||
end
|
end
|
||||||
|
|
||||||
def kmyblue_flag
|
def kmyblue_flag
|
||||||
|
|
|
@ -95,16 +95,11 @@ RSpec.describe ActivityPub::LinkedDataSignature do
|
||||||
describe '#sign!' do
|
describe '#sign!' do
|
||||||
subject { described_class.new(raw_json).sign!(sender) }
|
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
|
expect(subject).to be_a Hash
|
||||||
end
|
|
||||||
|
|
||||||
it 'contains signature' do
|
|
||||||
expect(subject['signature']).to be_a Hash
|
expect(subject['signature']).to be_a Hash
|
||||||
expect(subject['signature']['signatureValue']).to be_present
|
expect(subject['signature']['signatureValue']).to be_present
|
||||||
end
|
expect(Array(subject['@context'])).to include('https://w3id.org/security/v1')
|
||||||
|
|
||||||
it 'can be verified again' do
|
|
||||||
expect(described_class.new(subject).verify_actor!).to eq sender
|
expect(described_class.new(subject).verify_actor!).to eq sender
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,8 +51,8 @@ describe Admin::SystemCheck::SoftwareVersionCheck do
|
||||||
Fabricate(:software_update, version: '99.99.99', type: 'major', urgent: false)
|
Fabricate(:software_update, version: '99.99.99', type: 'major', urgent: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns true' do
|
it 'returns false' do
|
||||||
expect(check.pass?).to be true
|
expect(check.pass?).to be false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue