Skip to content

Commit a746364

Browse files
Implement safe file path validation in Zerobounce SDK
1 parent 06447da commit a746364

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
zerobounce-sdk (1.3.0)
4+
zerobounce-sdk (2.0.0)
55
dotenv
66
rest-client (~> 2.1)
77

lib/zerobounce/base_request.rb

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,26 @@ class BaseRequest
1313

1414
protected
1515

16+
# Resolves and validates filepath to prevent path traversal (e.g. ../../etc/passwd).
17+
# Returns a canonical path only if the file is under the current directory and is a regular file.
18+
def self.__safe_file_path__(filepath)
19+
raise ArgumentError, 'File path is required' if filepath.nil? || filepath.to_s.empty?
20+
expanded = File.expand_path(filepath)
21+
base = File.realpath(Dir.pwd)
22+
base_with_sep = base + File::SEPARATOR
23+
unless expanded == base || expanded.start_with?(base_with_sep)
24+
raise ArgumentError, 'File path must be under the current directory'
25+
end
26+
canonical = File.realpath(expanded)
27+
unless canonical == base || canonical.start_with?(base_with_sep)
28+
raise ArgumentError, 'File path must be under the current directory'
29+
end
30+
unless File.file?(canonical)
31+
raise ArgumentError, 'File path must point to a regular file'
32+
end
33+
canonical
34+
end
35+
1636
def self._get(root, path, params, content_type='application/json')
1737

1838
# puts path
@@ -36,7 +56,7 @@ def self._post(root, path, params, content_type='application/json', filepath=nil
3656
response = nil
3757

3858
if filepath or content_type == 'multipart/form-data'
39-
params[:file] = File.new(filepath, 'rb')
59+
params[:file] = File.new(self.class.__safe_file_path__(filepath), 'rb')
4060
params[:multipart] = true
4161
response = RestClient.post(url, params)
4262

0 commit comments

Comments
 (0)