Class: Gitlab::UrlBlocker
- Inherits:
-
Object
- Object
- Gitlab::UrlBlocker
- Defined in:
- lib/gitlab/url_blocker.rb
Defined Under Namespace
Classes: Result
Constant Summary collapse
- BlockedUrlError =
Class.new(StandardError)
- DENY_ALL_REQUESTS_EXCEPT_ALLOWED_DEFAULT =
proc { deny_all_requests_except_allowed_app_setting }.freeze
Class Method Summary collapse
- .blocked_url?(url, **kwargs) ⇒ Boolean
-
.validate! ⇒ Object
For backwards compatibility, Returns an array with [<uri>, <original-hostname>].
-
.validate_url_with_proxy!(url, schemes:, ports: [], allow_localhost: false, allow_local_network: true, allow_object_storage: false, ascii_only: false, enforce_user: false, enforce_sanitization: false, deny_all_requests_except_allowed: DENY_ALL_REQUESTS_EXCEPT_ALLOWED_DEFAULT, dns_rebind_protection: true) ⇒ Object
Validates the given url according to the constraints specified by arguments.
Class Method Details
.blocked_url?(url, **kwargs) ⇒ Boolean
111 112 113 114 115 116 117 |
# File 'lib/gitlab/url_blocker.rb', line 111 def blocked_url?(url, **kwargs) validate!(url, **kwargs) false rescue BlockedUrlError true end |
.validate! ⇒ Object
For backwards compatibility, Returns an array with [<uri>, <original-hostname>]. Issue for refactoring: gitlab.com/gitlab-org/gitlab/-/issues/410890
121 122 123 124 |
# File 'lib/gitlab/url_blocker.rb', line 121 def validate!(...) result = validate_url_with_proxy!(...) [result.uri, result.hostname] end |
.validate_url_with_proxy!(url, schemes:, ports: [], allow_localhost: false, allow_local_network: true, allow_object_storage: false, ascii_only: false, enforce_user: false, enforce_sanitization: false, deny_all_requests_except_allowed: DENY_ALL_REQUESTS_EXCEPT_ALLOWED_DEFAULT, dns_rebind_protection: true) ⇒ Object
Validates the given url according to the constraints specified by arguments.
ports - Raises error if the given URL port is not between given ports. allow_localhost - Raises error if URL resolves to a localhost IP address and argument is false. allow_local_network - Raises error if URL resolves to a link-local address and argument is false. allow_object_storage - Avoid raising an error if URL resolves to an object storage endpoint and argument is true. ascii_only - Raises error if URL has unicode characters and argument is true. enforce_user - Raises error if URL user doesn’t start with alphanumeric characters and argument is true. enforce_sanitization - Raises error if URL includes any HTML/CSS/JS tags and argument is true. deny_all_requests_except_allowed - Raises error if URL is not in the allow list and argument is true. Can be Boolean or Proc. Defaults to instance app setting.
Returns a Result object. rubocop:disable Metrics/ParameterLists
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/gitlab/url_blocker.rb', line 43 def validate_url_with_proxy!( url, schemes:, ports: [], allow_localhost: false, allow_local_network: true, allow_object_storage: false, ascii_only: false, enforce_user: false, enforce_sanitization: false, deny_all_requests_except_allowed: DENY_ALL_REQUESTS_EXCEPT_ALLOWED_DEFAULT, dns_rebind_protection: true) # rubocop:enable Metrics/ParameterLists return Result.new(nil, nil, true) if url.nil? raise ArgumentError, 'The schemes is a required argument' if schemes.blank? # Param url can be a string, URI or Addressable::URI uri = parse_url(url) validate_uri( uri: uri, schemes: schemes, ports: ports, enforce_sanitization: enforce_sanitization, enforce_user: enforce_user, ascii_only: ascii_only ) begin address_info = get_address_info(uri) rescue SocketError proxy_in_use = uri_under_proxy_setting?(uri, nil) return Result.new(uri, nil, proxy_in_use) unless enforce_address_info_retrievable?(uri, dns_rebind_protection, deny_all_requests_except_allowed) raise BlockedUrlError, 'Host cannot be resolved or invalid' end ip_address = ip_address(address_info) proxy_in_use = uri_under_proxy_setting?(uri, ip_address) # Ignore DNS rebind protection when a proxy is being used, as DNS # rebinding is expected behavior. dns_rebind_protection &&= !proxy_in_use return Result.new(uri, nil, proxy_in_use) if domain_in_allow_list?(uri) protected_uri_with_hostname = enforce_uri_hostname(ip_address, uri, dns_rebind_protection, proxy_in_use) return protected_uri_with_hostname if ip_in_allow_list?(ip_address, port: get_port(uri)) # Allow url from the GitLab instance itself but only for the configured hostname and ports return protected_uri_with_hostname if internal?(uri) return protected_uri_with_hostname if allow_object_storage && object_storage_endpoint?(uri) validate_deny_all_requests_except_allowed!(deny_all_requests_except_allowed) validate_local_request( address_info: address_info, allow_localhost: allow_localhost, allow_local_network: allow_local_network ) protected_uri_with_hostname end |