From 18a6f5a941f3b5777977693f3b59ac5d200928a8 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Sat, 20 Feb 2021 11:49:10 +0800 Subject: [PATCH] [Ruby] force users to specify the temp folder path to address security concerns (#8730) * address security issue when downloading files in the ruby client * update samples * fix double quote --- .../main/resources/ruby-client/api_client.mustache | 7 +++++++ .../ruby-client/api_client_typhoeus_partial.mustache | 11 ++++++++++- .../petstore/ruby-faraday/lib/petstore/api_client.rb | 7 +++++++ .../client/petstore/ruby/lib/petstore/api_client.rb | 9 +++++++++ .../ruby-client/lib/x_auth_id_alias/api_client.rb | 9 +++++++++ .../ruby/lib/dynamic_servers/api_client.rb | 10 +++++++++- .../ruby-client/lib/petstore/api_client.rb | 10 +++++++++- 7 files changed, 60 insertions(+), 3 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/ruby-client/api_client.mustache b/modules/openapi-generator/src/main/resources/ruby-client/api_client.mustache index 2741a73794e..7d2cc4a6cb5 100644 --- a/modules/openapi-generator/src/main/resources/ruby-client/api_client.mustache +++ b/modules/openapi-generator/src/main/resources/ruby-client/api_client.mustache @@ -71,6 +71,13 @@ module {{moduleName}} {{/isFaraday}} {{#isFaraday}} if return_type == 'File' + # throw an exception if the temp folder path is not defined + # to avoid using the default temp directory which can be read by anyone + if @config.temp_folder_path.nil? + raise "@config.temp_folder_path must be setup first (e.g. ENV[\"HOME\"], ENV[\"HOMEPATH\"]) " + + "to avoid dowloading the file to a location readable by everyone." + end + content_disposition = response.headers['Content-Disposition'] if content_disposition && content_disposition =~ /filename=/i filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] diff --git a/modules/openapi-generator/src/main/resources/ruby-client/api_client_typhoeus_partial.mustache b/modules/openapi-generator/src/main/resources/ruby-client/api_client_typhoeus_partial.mustache index e0c9e7cc1d6..496ba6c46fa 100644 --- a/modules/openapi-generator/src/main/resources/ruby-client/api_client_typhoeus_partial.mustache +++ b/modules/openapi-generator/src/main/resources/ruby-client/api_client_typhoeus_partial.mustache @@ -52,8 +52,8 @@ {{#hasAuthMethods}} update_params_for_auth! header_params, query_params, opts[:auth_names] - {{/hasAuthMethods}} + {{/hasAuthMethods}} # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false) _verify_ssl_host = @config.verify_ssl_host ? 2 : 0 @@ -122,6 +122,13 @@ # # @see Configuration#temp_folder_path def download_file(request) + # throw an exception if the temp folder path is not defined + # to avoid using the default temp directory which can be read by anyone + if @config.temp_folder_path.nil? + raise "@config.temp_folder_path must be setup first (e.g. ENV[\"HOME\"], ENV[\"HOMEPATH\"])" + + "to avoid dowloading the file to a location readable by everyone." + end + tempfile = nil encoding = nil request.on_headers do |response| @@ -137,10 +144,12 @@ tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) @tempfile = tempfile end + request.on_body do |chunk| chunk.force_encoding(encoding) tempfile.write(chunk) end + request.on_complete do |response| if tempfile tempfile.close diff --git a/samples/client/petstore/ruby-faraday/lib/petstore/api_client.rb b/samples/client/petstore/ruby-faraday/lib/petstore/api_client.rb index 6bb453bf498..58682d45a4c 100644 --- a/samples/client/petstore/ruby-faraday/lib/petstore/api_client.rb +++ b/samples/client/petstore/ruby-faraday/lib/petstore/api_client.rb @@ -203,6 +203,13 @@ module Petstore # handle file downloading - return the File instance processed in request callbacks # note that response body is empty when the file is written in chunks in request on_body callback if return_type == 'File' + # throw an exception if the temp folder path is not defined + # to avoid using the default temp directory which can be read by anyone + if @config.temp_folder_path.nil? + raise "@config.temp_folder_path must be setup first (e.g. ENV[\"HOME\"], ENV[\"HOMEPATH\"]) " + + "to avoid dowloading the file to a location readable by everyone." + end + content_disposition = response.headers['Content-Disposition'] if content_disposition && content_disposition =~ /filename=/i filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] diff --git a/samples/client/petstore/ruby/lib/petstore/api_client.rb b/samples/client/petstore/ruby/lib/petstore/api_client.rb index bc82c400eac..e0d78ae6f87 100644 --- a/samples/client/petstore/ruby/lib/petstore/api_client.rb +++ b/samples/client/petstore/ruby/lib/petstore/api_client.rb @@ -164,6 +164,13 @@ module Petstore # # @see Configuration#temp_folder_path def download_file(request) + # throw an exception if the temp folder path is not defined + # to avoid using the default temp directory which can be read by anyone + if @config.temp_folder_path.nil? + raise "@config.temp_folder_path must be setup first (e.g. ENV[\"HOME\"], ENV[\"HOMEPATH\"])" + + "to avoid dowloading the file to a location readable by everyone." + end + tempfile = nil encoding = nil request.on_headers do |response| @@ -179,10 +186,12 @@ module Petstore tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) @tempfile = tempfile end + request.on_body do |chunk| chunk.force_encoding(encoding) tempfile.write(chunk) end + request.on_complete do |response| if tempfile tempfile.close diff --git a/samples/openapi3/client/extensions/x-auth-id-alias/ruby-client/lib/x_auth_id_alias/api_client.rb b/samples/openapi3/client/extensions/x-auth-id-alias/ruby-client/lib/x_auth_id_alias/api_client.rb index c369f53d3f8..38759a537e2 100644 --- a/samples/openapi3/client/extensions/x-auth-id-alias/ruby-client/lib/x_auth_id_alias/api_client.rb +++ b/samples/openapi3/client/extensions/x-auth-id-alias/ruby-client/lib/x_auth_id_alias/api_client.rb @@ -164,6 +164,13 @@ module XAuthIDAlias # # @see Configuration#temp_folder_path def download_file(request) + # throw an exception if the temp folder path is not defined + # to avoid using the default temp directory which can be read by anyone + if @config.temp_folder_path.nil? + raise "@config.temp_folder_path must be setup first (e.g. ENV[\"HOME\"], ENV[\"HOMEPATH\"])" + + "to avoid dowloading the file to a location readable by everyone." + end + tempfile = nil encoding = nil request.on_headers do |response| @@ -179,10 +186,12 @@ module XAuthIDAlias tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) @tempfile = tempfile end + request.on_body do |chunk| chunk.force_encoding(encoding) tempfile.write(chunk) end + request.on_complete do |response| if tempfile tempfile.close diff --git a/samples/openapi3/client/features/dynamic-servers/ruby/lib/dynamic_servers/api_client.rb b/samples/openapi3/client/features/dynamic-servers/ruby/lib/dynamic_servers/api_client.rb index 8ae4ab399d1..bfd29c6e0ad 100644 --- a/samples/openapi3/client/features/dynamic-servers/ruby/lib/dynamic_servers/api_client.rb +++ b/samples/openapi3/client/features/dynamic-servers/ruby/lib/dynamic_servers/api_client.rb @@ -94,7 +94,6 @@ module DynamicServers query_params = opts[:query_params] || {} form_params = opts[:form_params] || {} - # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false) _verify_ssl_host = @config.verify_ssl_host ? 2 : 0 @@ -163,6 +162,13 @@ module DynamicServers # # @see Configuration#temp_folder_path def download_file(request) + # throw an exception if the temp folder path is not defined + # to avoid using the default temp directory which can be read by anyone + if @config.temp_folder_path.nil? + raise "@config.temp_folder_path must be setup first (e.g. ENV[\"HOME\"], ENV[\"HOMEPATH\"])" + + "to avoid dowloading the file to a location readable by everyone." + end + tempfile = nil encoding = nil request.on_headers do |response| @@ -178,10 +184,12 @@ module DynamicServers tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) @tempfile = tempfile end + request.on_body do |chunk| chunk.force_encoding(encoding) tempfile.write(chunk) end + request.on_complete do |response| if tempfile tempfile.close diff --git a/samples/openapi3/client/features/generate-alias-as-model/ruby-client/lib/petstore/api_client.rb b/samples/openapi3/client/features/generate-alias-as-model/ruby-client/lib/petstore/api_client.rb index 5fc4263b17a..740adf9c617 100644 --- a/samples/openapi3/client/features/generate-alias-as-model/ruby-client/lib/petstore/api_client.rb +++ b/samples/openapi3/client/features/generate-alias-as-model/ruby-client/lib/petstore/api_client.rb @@ -94,7 +94,6 @@ module Petstore query_params = opts[:query_params] || {} form_params = opts[:form_params] || {} - # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false) _verify_ssl_host = @config.verify_ssl_host ? 2 : 0 @@ -163,6 +162,13 @@ module Petstore # # @see Configuration#temp_folder_path def download_file(request) + # throw an exception if the temp folder path is not defined + # to avoid using the default temp directory which can be read by anyone + if @config.temp_folder_path.nil? + raise "@config.temp_folder_path must be setup first (e.g. ENV[\"HOME\"], ENV[\"HOMEPATH\"])" + + "to avoid dowloading the file to a location readable by everyone." + end + tempfile = nil encoding = nil request.on_headers do |response| @@ -178,10 +184,12 @@ module Petstore tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) @tempfile = tempfile end + request.on_body do |chunk| chunk.force_encoding(encoding) tempfile.write(chunk) end + request.on_complete do |response| if tempfile tempfile.close