Change link verification to ignore IDN domains (#20295)

Fix #3833
This commit is contained in:
Eugen Rochko 2022-11-10 06:27:45 +01:00 committed by GitHub
parent c4ff2640c1
commit ea7cc10811
2 changed files with 23 additions and 1 deletions

View file

@ -3,6 +3,7 @@
class Account::Field < ActiveModelSerializers::Model
MAX_CHARACTERS_LOCAL = 255
MAX_CHARACTERS_COMPAT = 2_047
ACCEPTED_SCHEMES = %w(http https).freeze
attributes :name, :value, :verified_at, :account
@ -34,7 +35,20 @@ class Account::Field < ActiveModelSerializers::Model
end
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
def requires_verification?

View file

@ -66,6 +66,14 @@ RSpec.describe Account::Field, type: :model do
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
let(:value) { 'Hello world' }