Change link verification to ignore IDN domains (#20295)

Fix #3833
main
Eugen Rochko 2022-11-10 06:27:45 +01:00 committed by GitHub
parent 78a6b871fe
commit 9965a23b04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 1 deletions

View File

@ -3,6 +3,7 @@
class Account::Field < ActiveModelSerializers::Model class Account::Field < ActiveModelSerializers::Model
MAX_CHARACTERS_LOCAL = 255 MAX_CHARACTERS_LOCAL = 255
MAX_CHARACTERS_COMPAT = 2_047 MAX_CHARACTERS_COMPAT = 2_047
ACCEPTED_SCHEMES = %w(http https).freeze
attributes :name, :value, :verified_at, :account attributes :name, :value, :verified_at, :account
@ -34,7 +35,20 @@ class Account::Field < ActiveModelSerializers::Model
end end
def verifiable? def verifiable?
value_for_verification.present? && /\A#{FetchLinkCardService::URL_PATTERN}\z/.match?(value_for_verification) return false if value_for_verification.blank?
# This is slower than checking through a regular expression, but we
# need to confirm that it's not an IDN domain.
parsed_url = Addressable::URI.parse(value_for_verification)
ACCEPTED_SCHEMES.include?(parsed_url.scheme) &&
parsed_url.user.nil? &&
parsed_url.password.nil? &&
parsed_url.host.present? &&
parsed_url.normalized_host == parsed_url.host
rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError
false
end end
def requires_verification? def requires_verification?

View File

@ -66,6 +66,14 @@ RSpec.describe Account::Field, type: :model do
end end
end end
context 'for an IDN URL' do
let(:value) { 'http://twitter.comdougalljstatus1590357240443437057.ê.cc/twitter.html' }
it 'returns false' do
expect(subject.verifiable?).to be false
end
end
context 'for text that is not a URL' do context 'for text that is not a URL' do
let(:value) { 'Hello world' } let(:value) { 'Hello world' }