From c627e8e61a65841b8db8017ad17560ad0bf88f9b Mon Sep 17 00:00:00 2001 From: Artem Tykhonov Date: Thu, 19 Sep 2024 16:11:16 +0300 Subject: [PATCH 1/2] Fix code scanning alert #9: Server-side request forgery Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- fastlane/helper/plugin_scores_helper.rb | 83 ++++++++++++++----------- 1 file changed, 48 insertions(+), 35 deletions(-) diff --git a/fastlane/helper/plugin_scores_helper.rb b/fastlane/helper/plugin_scores_helper.rb index 756582d7665..76ef23687b5 100644 --- a/fastlane/helper/plugin_scores_helper.rb +++ b/fastlane/helper/plugin_scores_helper.rb @@ -235,48 +235,61 @@ def append_git_data end end + # Validate the GitHub URL against a whitelist + def valid_github_url?(url) + allowed_urls = [ + "https://github.com/fastlane/fastlane", + # Add more allowed URLs here + ] + allowed_urls.any? { |allowed_url| url.start_with?(allowed_url) } + end + # Everything from the GitHub API (e.g. open issues and stars) def append_github_data # e.g. https://api.github.com/repos/fastlane/fastlane - url = self.homepage.gsub("github.com/", "api.github.com/repos/") - url = url[0..-2] if url.end_with?("/") # what is this, 2001? We got to remove the trailing `/` otherwise GitHub will fail - puts("Fetching #{url}") - conn = Faraday.new(url: url) do |builder| - # The order below IS important - # See bug here https://github.com/lostisland/faraday_middleware/issues/105 - builder.use(FaradayMiddleware::FollowRedirects) - builder.adapter(Faraday.default_adapter) - end - conn.basic_auth(ENV["GITHUB_USER_NAME"], ENV["GITHUB_API_TOKEN"]) - response = conn.get('') - repo_details = JSON.parse(response.body) - - url += "/stats/contributors" - puts("Fetching #{url}") - conn = Faraday.new(url: url) do |builder| - # The order below IS important - # See bug here https://github.com/lostisland/faraday_middleware/issues/105 - builder.use(FaradayMiddleware::FollowRedirects) - builder.adapter(Faraday.default_adapter) - end + if valid_github_url?(self.homepage) + url = self.homepage.gsub("github.com/", "api.github.com/repos/") + url = url[0..-2] if url.end_with?("/") # what is this, 2001? We got to remove the trailing `/` otherwise GitHub will fail + puts("Fetching #{url}") + conn = Faraday.new(url: url) do |builder| + # The order below IS important + # See bug here https://github.com/lostisland/faraday_middleware/issues/105 + builder.use(FaradayMiddleware::FollowRedirects) + builder.adapter(Faraday.default_adapter) + end + conn.basic_auth(ENV["GITHUB_USER_NAME"], ENV["GITHUB_API_TOKEN"]) + response = conn.get('') + repo_details = JSON.parse(response.body) + + url += "/stats/contributors" + puts("Fetching #{url}") + conn = Faraday.new(url: url) do |builder| + # The order below IS important + # See bug here https://github.com/lostisland/faraday_middleware/issues/105 + builder.use(FaradayMiddleware::FollowRedirects) + builder.adapter(Faraday.default_adapter) + end - conn.basic_auth(ENV["GITHUB_USER_NAME"], ENV["GITHUB_API_TOKEN"]) - response = conn.get('') - contributor_details = JSON.parse(response.body) + conn.basic_auth(ENV["GITHUB_USER_NAME"], ENV["GITHUB_API_TOKEN"]) + response = conn.get('') + contributor_details = JSON.parse(response.body) - self.data[:github_stars] = repo_details["stargazers_count"].to_i - self.data[:github_subscribers] = repo_details["subscribers_count"].to_i - self.data[:github_issues] = repo_details["open_issues_count"].to_i - self.data[:github_forks] = repo_details["forks_count"].to_i - self.data[:github_contributors] = contributor_details.count + self.data[:github_stars] = repo_details["stargazers_count"].to_i + self.data[:github_subscribers] = repo_details["subscribers_count"].to_i + self.data[:github_issues] = repo_details["open_issues_count"].to_i + self.data[:github_forks] = repo_details["forks_count"].to_i + self.data[:github_contributors] = contributor_details.count - cache_data = self.cache[self.name] + cache_data = self.cache[self.name] - cache_data[:github_stars] = self.data[:github_stars] - cache_data[:github_subscribers] = self.data[:github_subscribers] - cache_data[:github_issues] = self.data[:github_issues] - cache_data[:github_forks] = self.data[:github_forks] - cache_data[:github_contributors] = self.data[:github_contributors] + cache_data[:github_stars] = self.data[:github_stars] + cache_data[:github_subscribers] = self.data[:github_subscribers] + cache_data[:github_issues] = self.data[:github_issues] + cache_data[:github_forks] = self.data[:github_forks] + cache_data[:github_contributors] = self.data[:github_contributors] + else + raise "Invalid GitHub URL: #{self.homepage}" + end rescue => ex puts("error fetching #{self}") puts(self.homepage) From a456c362a69c6e8f3f9b34120bd718419e70ff3b Mon Sep 17 00:00:00 2001 From: Artem Tykhonov Date: Thu, 19 Sep 2024 16:26:29 +0300 Subject: [PATCH 2/2] Apply code scanning fix for server-side request forgery Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- fastlane/helper/plugin_scores_helper.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fastlane/helper/plugin_scores_helper.rb b/fastlane/helper/plugin_scores_helper.rb index 76ef23687b5..e3d11950fa6 100644 --- a/fastlane/helper/plugin_scores_helper.rb +++ b/fastlane/helper/plugin_scores_helper.rb @@ -245,9 +245,14 @@ def valid_github_url?(url) end # Everything from the GitHub API (e.g. open issues and stars) + ALLOWED_GITHUB_REPOS = [ + "https://github.com/fastlane/fastlane", + "https://github.com/fastlane/other-repo" + ] + def append_github_data # e.g. https://api.github.com/repos/fastlane/fastlane - if valid_github_url?(self.homepage) + if valid_github_url?(self.homepage) && ALLOWED_GITHUB_REPOS.include?(self.homepage) url = self.homepage.gsub("github.com/", "api.github.com/repos/") url = url[0..-2] if url.end_with?("/") # what is this, 2001? We got to remove the trailing `/` otherwise GitHub will fail puts("Fetching #{url}") @@ -288,7 +293,7 @@ def append_github_data cache_data[:github_forks] = self.data[:github_forks] cache_data[:github_contributors] = self.data[:github_contributors] else - raise "Invalid GitHub URL: #{self.homepage}" + raise "Invalid or unauthorized GitHub URL: #{self.homepage}" end rescue => ex puts("error fetching #{self}")