Module: Aikido::Zen::Scanners::PathTraversal::Helpers

Defined in:
lib/aikido/zen/scanners/path_traversal/helpers.rb

Class Method Summary collapse

Class Method Details

.include_unsafe_path_parts?(filepath) ⇒ Boolean

Returns:

  • (Boolean)


48
49
50
51
52
53
54
# File 'lib/aikido/zen/scanners/path_traversal/helpers.rb', line 48

def self.include_unsafe_path_parts?(filepath)
  DANGEROUS_PATH_PARTS.each do |dangerous_part|
    return true if filepath.include?(dangerous_part)
  end

  false
end

.start_with_unsafe_path?(filepath, user_input) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/aikido/zen/scanners/path_traversal/helpers.rb', line 56

def self.start_with_unsafe_path?(filepath, user_input)
  # Check if path is relative (not absolute or drive letter path)
  # Required because `expand_path` will build absolute paths from relative paths
  return false if Pathname.new(filepath).relative? || Pathname.new(user_input).relative?

  normalized_path = File.expand_path__internal_for_aikido_zen(filepath).downcase.squeeze("/")
  normalized_user_input = File.expand_path__internal_for_aikido_zen(user_input).downcase.squeeze("/")

  DANGEROUS_PATH_STARTS.each do |dangerous_start|
    if normalized_path.start_with?(dangerous_start) && normalized_path.start_with?(normalized_user_input)
      # If the user input is the same as the dangerous start, we don't want to flag it
      # to prevent false positives.
      # e.g., if user input is /etc/ and the path is /etc/passwd, we don't want to flag it,
      # as long as the user input does not contain a subdirectory or filename
      return false if user_input == dangerous_start || user_input == dangerous_start.chomp("/")

      return true
    end
  end

  false
end