diff --git a/app/models/project.rb b/app/models/project.rb
index 0bb815e64e7c62bfaa2ec03648ec1bdaae876757..a3f78349e9855f5d5a39bb805179e96242d36670 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -153,9 +153,7 @@ class Project < ActiveRecord::Base
   validates :namespace, presence: true
   validates_uniqueness_of :name, scope: :namespace_id
   validates_uniqueness_of :path, scope: :namespace_id
-  validates :import_url,
-    url: { protocols: %w(ssh git http https) },
-    if: :external_import?
+  validates :import_url, addressable_url: true, if: :external_import?
   validates :star_count, numericality: { greater_than_or_equal_to: 0 }
   validate :check_limit, on: :create
   validate :avatar_type,
diff --git a/app/validators/addressable_url_validator.rb b/app/validators/addressable_url_validator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4e1a01a1bff3ab2624f34609c87b6833b6147c9e
--- /dev/null
+++ b/app/validators/addressable_url_validator.rb
@@ -0,0 +1,49 @@
+# UrlValidator
+#
+# Custom validator for URLs.
+#
+# By default, only URLs for the HTTP(S) protocols will be considered valid.
+# Provide a `:protocols` option to configure accepted protocols.
+#
+# Example:
+#
+#   class User < ActiveRecord::Base
+#     validates :personal_url, url: true
+#
+#     validates :ftp_url, url: { protocols: %w(ftp) }
+#
+#     validates :git_url, url: { protocols: %w(http https ssh git) }
+#   end
+#
+class AddressableUrlValidator < ActiveModel::EachValidator
+  def validate_each(record, attribute, value)
+    unless valid_url?(value)
+      record.errors.add(attribute, "must be a valid URL")
+    end
+  end
+
+  private
+
+  def default_options
+    @default_options ||= { protocols: %w(http https ssh git) }
+  end
+
+  def valid_url?(value)
+    return false unless value
+
+    value.strip!
+
+    valid_uri?(value) && valid_protocol?(value)
+  rescue Addressable::URI::InvalidURIError
+    false
+  end
+
+  def valid_uri?(value)
+    Addressable::URI.parse(strip).is_a?(Addressable::URI)
+  end
+
+  def valid_protocol?(value)
+    options = default_options.merge(self.options)
+    value =~ /\A#{URI.regexp(options[:protocols])}\z/
+  end
+end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index fedab1f913bb430f063fd62e013a8bb312b2597f..c99fd7c633ece936432a7c4ad1a1e6e13eb739dd 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -63,6 +63,11 @@ describe Project, models: true do
       expect(project2).not_to be_valid
       expect(project2.errors[:limit_reached].first).to match(/Personal project creation is not allowed/)
     end
+
+    it 'should not allow an invalid URI as import_url' do
+      project2 = build(:project)
+      expect(project2).to be_valid
+    end
   end
 
   describe 'default_scope' do