Class: AddressableUrlValidator
- Inherits:
-
ActiveModel::EachValidator
- Object
- ActiveModel::EachValidator
- AddressableUrlValidator
- Defined in:
- app/validators/addressable_url_validator.rb
Overview
AddressableUrlValidator
Custom validator for URLs. This is a stricter version of UrlValidator - it also checks for using the right protocol, but it actually parses the URL checking for any syntax errors. The regex is also different from ‘URI` as we use `Addressable::URI` here.
By default, only URLs for the HTTP(S) schemes will be considered valid. Provide a ‘:schemes` option to configure accepted schemes.
Example:
class User < ActiveRecord::Base
validates :personal_url, addressable_url: true
validates :ftp_url, addressable_url: { schemes: %w(ftp) }
validates :git_url, addressable_url: { schemes: %w(http https ssh git) }
end
This validator can also block urls pointing to localhost or the local network to protect against Server-side Request Forgery (SSRF), or check for the right port.
Configuration options:
-
message
- A custom error message, used when the URL is blank. (default is: “must be a valid URL”). -
blocked_message
- A custom error message, used when the URL is blocked. Default: ‘is blocked: %{exception_message}’. -
schemes
- Array of URI schemes. Default: [‘http’, ‘https’] -
allow_localhost
- Allow urls pointing tolocalhost
. Default:true
-
allow_local_network
- Allow urls pointing to private network addresses. Default:true
-
allow_blank
- Allow urls to beblank
. Default:false
-
allow_nil
- Allow urls to benil
. Default:false
-
ports
- Allowed ports. Default:all
. -
deny_all_requests_except_allowed
- Deny all requests. Default: Respects the instance app setting.Note: Regardless of whether enforced during validation, an HTTP request that uses the URI may still be blocked.
-
enforce_user
- Validate user format. Default:false
-
enforce_sanitization
- Validate that there are no html/css/js tags. Default:false
Example:
class User < ActiveRecord::Base
validates :personal_url, addressable_url: { allow_localhost: false, allow_local_network: false}
validates :web_url, addressable_url: { ports: [80, 443] }
end
Direct Known Subclasses
Constant Summary collapse
- DENY_ALL_REQUESTS_EXCEPT_ALLOWED_DEFAULT =
proc { deny_all_requests_except_allowed? }.freeze
- BLOCKER_VALIDATE_OPTIONS =
By default, we avoid checking the dns rebinding protection when saving/updating a record. Sometimes, the url is not resolvable at that point, and some automated tasks that uses that url won’t work. See gitlab.com/gitlab-org/gitlab-foss/issues/66723
{ schemes: %w[http https], ports: [], allow_localhost: true, allow_local_network: true, ascii_only: false, deny_all_requests_except_allowed: DENY_ALL_REQUESTS_EXCEPT_ALLOWED_DEFAULT, enforce_user: false, enforce_sanitization: false, dns_rebind_protection: false, outbound_local_requests_allowlist: [] }.freeze
- DEFAULT_OPTIONS =
BLOCKER_VALIDATE_OPTIONS.merge({ message: 'must be a valid URL', blocked_message: 'is blocked: %{exception_message}' }).freeze
Instance Attribute Summary collapse
-
#record ⇒ Object
readonly
Returns the value of attribute record.
Instance Method Summary collapse
-
#initialize(options) ⇒ AddressableUrlValidator
constructor
A new instance of AddressableUrlValidator.
- #validate_each(record, attribute, value) ⇒ Object
Constructor Details
#initialize(options) ⇒ AddressableUrlValidator
Returns a new instance of AddressableUrlValidator.
73 74 75 76 77 |
# File 'app/validators/addressable_url_validator.rb', line 73 def initialize() .reverse_merge!(DEFAULT_OPTIONS) super() end |
Instance Attribute Details
#record ⇒ Object (readonly)
Returns the value of attribute record.
46 47 48 |
# File 'app/validators/addressable_url_validator.rb', line 46 def record @record end |
Instance Method Details
#validate_each(record, attribute, value) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'app/validators/addressable_url_validator.rb', line 79 def validate_each(record, attribute, value) @record = record unless value.present? record.errors.add(attribute, .fetch(:message)) return end value = strip_value!(record, attribute, value) Gitlab::HTTP_V2::UrlBlocker.validate!(value, **blocker_args) rescue Gitlab::HTTP_V2::UrlBlocker::BlockedUrlError => e record.errors.add(attribute, .fetch(:blocked_message) % { exception_message: e. }) end |