From 926b726ab1ca8d51622d4865ac585e6eb9093b42 Mon Sep 17 00:00:00 2001 From: as-op Date: Tue, 19 May 2026 16:20:42 +0200 Subject: [PATCH] [#75031] Imprecise error for unallowed IP when testing Jira connection https://community.openproject.org/wp/75031 --- app/controllers/admin/import/jira/instances_controller.rb | 3 +++ app/services/import/jira_client.rb | 6 ++++++ config/locales/en.yml | 5 +++++ config/static_links.yml | 2 ++ 4 files changed, 16 insertions(+) diff --git a/app/controllers/admin/import/jira/instances_controller.rb b/app/controllers/admin/import/jira/instances_controller.rb index b12f524f674..d74bc28de4d 100644 --- a/app/controllers/admin/import/jira/instances_controller.rb +++ b/app/controllers/admin/import/jira/instances_controller.rb @@ -129,6 +129,9 @@ module Admin::Import::Jira def handle_test_error(error) message = case error + when Import::JiraClient::SsrfError + link_translate("admin.jira.client.ssrf_block_doc_link", + links: { docs_url: %i[sysadmin_docs ssrf_protection] }).prepend("#{error.message} ") when Import::JiraClient::ConnectionError then t(:"admin.jira.test.connection_error", message: error.message) when Import::JiraClient::ParseError then t(:"admin.jira.test.parse_error") when Import::JiraClient::ApiError then t(:"admin.jira.test.api_error", status: error.status) diff --git a/app/services/import/jira_client.rb b/app/services/import/jira_client.rb index f6c848967c9..e348c0f5b9a 100644 --- a/app/services/import/jira_client.rb +++ b/app/services/import/jira_client.rb @@ -34,6 +34,8 @@ module Import class ConnectionError < Error; end + class SsrfError < ConnectionError; end + class ParseError < Error; end class ApiError < Error @@ -262,6 +264,8 @@ module Import end end nil + rescue SsrfFilter::PrivateIPAddress + raise SsrfError, I18n.t("admin.jira.client.ssrf_blocked") rescue SsrfFilter::Error => e raise ConnectionError, I18n.t("admin.jira.client.connection_error", message: e.message) rescue Timeout::Error => e @@ -284,6 +288,8 @@ module Import params:, http_options: HTTP_OPTIONS ) + rescue SsrfFilter::PrivateIPAddress + raise SsrfError, I18n.t("admin.jira.client.ssrf_blocked") rescue SsrfFilter::Error, SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH => e raise ConnectionError, I18n.t("admin.jira.client.connection_error", message: e.message) rescue Timeout::Error => e diff --git a/config/locales/en.yml b/config/locales/en.yml index b020f414bf9..254aeace910 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -163,6 +163,11 @@ en: client: connection_error: "Failed to connect to Jira server: %{message}" connection_timeout: "Connection to Jira server timed out: %{message}" + ssrf_blocked: >- + Connection blocked: the Jira host resolves to a private IP address. If your Jira instance + runs on an internal network, allow its IP via the OPENPROJECT_SSRF__PROTECTION__IP__ALLOWLIST + environment variable. + ssrf_block_doc_link: "Please see our [documentation](docs_url)." parse_error: "Failed to parse Jira API response: %{message}" api_error: "Jira API returned error status %{status}" 401_error: "Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator." diff --git a/config/static_links.yml b/config/static_links.yml index 41255a2c525..76193f7d16c 100644 --- a/config/static_links.yml +++ b/config/static_links.yml @@ -206,6 +206,8 @@ sysadmin_docs: href: https://www.openproject.org/docs/system-admin-guide/authentication/scim/#step-3-choose-an-authentication-method scim_jwt_authetication_method: href: https://www.openproject.org/docs/system-admin-guide/authentication/scim/#c-jwt-from-identity-provider + ssrf_protection: + href: https://www.openproject.org/docs/installation-and-operations/configuration/ssrf-protection/ terms_of_service: href: https://www.openproject.org/terms-of-service/ text_formatting: