From f13198d524e5703deccef429fef1af4f2b15b089 Mon Sep 17 00:00:00 2001 From: Bell Isabell Date: Tue, 3 Mar 2026 18:49:44 -0800 Subject: [PATCH] Add HTTP timeouts to all Net::HTTP requests Security fix: All Net::HTTP requests now have open_timeout=5 and read_timeout=10 to prevent hanging on unresponsive external services. Files updated: - app/models/domain.rb (render_service_request and liveness_check) - app/jobs/post_in_admin_chat_job.rb - app/jobs/subscribe_to_contraption_ghost_job.rb Closes #21 --- app/jobs/post_in_admin_chat_job.rb | 2 +- app/jobs/subscribe_to_contraption_ghost_job.rb | 2 +- app/models/domain.rb | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/jobs/post_in_admin_chat_job.rb b/app/jobs/post_in_admin_chat_job.rb index af50d86..b55bf37 100644 --- a/app/jobs/post_in_admin_chat_job.rb +++ b/app/jobs/post_in_admin_chat_job.rb @@ -18,7 +18,7 @@ def perform(message) request = Net::HTTP::Post.new(uri, "Content-Type" => "text/plain; charset=utf-8") request.body = message - response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http| + response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https", open_timeout: 5, read_timeout: 10) do |http| http.request(request) end diff --git a/app/jobs/subscribe_to_contraption_ghost_job.rb b/app/jobs/subscribe_to_contraption_ghost_job.rb index e08fbe0..c0c1001 100644 --- a/app/jobs/subscribe_to_contraption_ghost_job.rb +++ b/app/jobs/subscribe_to_contraption_ghost_job.rb @@ -15,7 +15,7 @@ def perform(email, name = nil) request.body = body.to_json - response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http| + response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https', open_timeout: 5, read_timeout: 10) do |http| http.request(request) end diff --git a/app/models/domain.rb b/app/models/domain.rb index ced00a9..9257cfe 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -104,6 +104,8 @@ def self.render_service_request(path, method, body = nil) # rubocop:disable Metr url = URI("https://api.render.com/v1/services/#{Rails.configuration.render[:service]}/custom-domains#{path}") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true + http.open_timeout = 5 + http.read_timeout = 10 request = method.new(url) request['Accept'] = 'application/json' request['Content-Type'] = 'application/json' if body.present? @@ -134,6 +136,8 @@ def liveness_check url = URI("https://#{domain}/.postcard") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true + http.open_timeout = 5 + http.read_timeout = 10 request = Net::HTTP::Get.new(url) http.request(request) end