Module: Gitlab::PathTraversal
Constant Summary collapse
- PathTraversalAttackError =
Class.new(StandardError)
- PATH_TRAVERSAL_REGEX =
%r{\A(\.{1,2})\z|\A\.\.[/\\]|[/\\]\.\.\z|[/\\]\.\.[/\\]}- PATH_TRAVERSAL_REGEX_WITH_NEWLINE =
%r{(#{PATH_TRAVERSAL_REGEX}|\n)}
Instance Method Summary collapse
- #check_allowed_absolute_path!(path, allowlist) ⇒ Object
- #check_allowed_absolute_path_and_path_traversal!(path, path_allowlist) ⇒ Object
-
#check_path_traversal!(path) ⇒ Object
Ensure that the relative path will not traverse outside the base directory We url decode the path to avoid passing invalid paths forward in url encoded format.
- #path_traversal?(decoded_path, match_new_line: true) ⇒ Boolean
Instance Method Details
#check_allowed_absolute_path!(path, allowlist) ⇒ Object
47 48 49 50 51 52 |
# File 'lib/gitlab/path_traversal.rb', line 47 def check_allowed_absolute_path!(path, allowlist) return unless Pathname.new(path).absolute? return if ::Gitlab::Utils.allowlisted?(path, allowlist) raise StandardError, "path #{path} is not allowed" end |
#check_allowed_absolute_path_and_path_traversal!(path, path_allowlist) ⇒ Object
54 55 56 57 58 59 |
# File 'lib/gitlab/path_traversal.rb', line 54 def check_allowed_absolute_path_and_path_traversal!(path, path_allowlist) traversal_path = check_path_traversal!(path) raise StandardError, "path is not a string!" unless traversal_path.is_a?(String) check_allowed_absolute_path!(traversal_path, path_allowlist) end |
#check_path_traversal!(path) ⇒ Object
Ensure that the relative path will not traverse outside the base directory We url decode the path to avoid passing invalid paths forward in url encoded format. Also see gitlab.com/gitlab-org/gitlab/-/merge_requests/24223#note_284122580 It also checks for backslash ‘\’, which is sometimes a File::ALT_SEPARATOR.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/gitlab/path_traversal.rb', line 19 def check_path_traversal!(path) return unless path path = path.to_s if path.is_a?(Gitlab::HashedPath) raise PathTraversalAttackError, 'Invalid path' unless path.is_a?(String) path = ::Gitlab::Utils.decode_path(path) if path_traversal?(path) logger.warn(message: "Potential path traversal attempt detected", path: path.to_s) raise PathTraversalAttackError, 'Invalid path' end path end |
#path_traversal?(decoded_path, match_new_line: true) ⇒ Boolean
35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/gitlab/path_traversal.rb', line 35 def path_traversal?(decoded_path, match_new_line: true) return false unless decoded_path regex = if match_new_line PATH_TRAVERSAL_REGEX_WITH_NEWLINE else PATH_TRAVERSAL_REGEX end decoded_path.match?(regex) end |