From 0cab72c795bb6e8fce431886d03fee8967a6045d Mon Sep 17 00:00:00 2001 From: Bartosz Janusz Date: Tue, 7 Jul 2026 11:37:04 +0200 Subject: [PATCH] [github]: Add `avatars` and `media` subdomains to authorized hosts list Added to handle avatars loading for GHE #IJPL-244623 Fixed (cherry picked from commit c6bab30d9a08b50caf1da8c8e01c7cd1a4fc004f) IJ-CR-216402 GitOrigin-RevId: 5adc21820cec529637eec0cce9dca434628242b6 --- .../plugins/github/api/GithubApiRequestExecutor.kt | 4 ++++ .../github/api/GithubApiRequestExecutorAuthTest.kt | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/plugins/github/github-core/src/org/jetbrains/plugins/github/api/GithubApiRequestExecutor.kt b/plugins/github/github-core/src/org/jetbrains/plugins/github/api/GithubApiRequestExecutor.kt index a5bccff6dff4..7f3595212ce9 100644 --- a/plugins/github/github-core/src/org/jetbrains/plugins/github/api/GithubApiRequestExecutor.kt +++ b/plugins/github/github-core/src/org/jetbrains/plugins/github/api/GithubApiRequestExecutor.kt @@ -285,11 +285,15 @@ sealed class GithubApiRequestExecutor { val ghDotComRawHost = "raw.githubusercontent.com" val enterpriseRawHost = "raw.$mainHost" // If GH Enterprise serves raw files from raw. + val enterpriseAvatarHost = "avatars.$mainHost" // GHE serves avatars from avatars. + val enterpriseMediaHost = "media.$mainHost" // GHE serves media attachments from media. val hostMatches = when { targetHost == mainHost -> true targetHost == apiHost -> true targetHost == enterpriseRawHost -> true + targetHost == enterpriseAvatarHost -> true + targetHost == enterpriseMediaHost -> true serverPath.isGithubDotCom || serverPath.isGheDataResidency -> targetHost == ghDotComRawHost else -> false } diff --git a/plugins/github/github-core/test/org/jetbrains/plugins/github/api/GithubApiRequestExecutorAuthTest.kt b/plugins/github/github-core/test/org/jetbrains/plugins/github/api/GithubApiRequestExecutorAuthTest.kt index 73b4c2c73fba..22fea0550c91 100644 --- a/plugins/github/github-core/test/org/jetbrains/plugins/github/api/GithubApiRequestExecutorAuthTest.kt +++ b/plugins/github/github-core/test/org/jetbrains/plugins/github/api/GithubApiRequestExecutorAuthTest.kt @@ -39,9 +39,11 @@ class GithubApiRequestExecutorAuthTest { @ValueSource(strings = [ "https://ghe.mycorp.local/myorg/repo", "https://raw.ghe.mycorp.local/myorg/repo/v1/action.yml", - "https://ghe.mycorp.local/myorg/repo/raw/v1/action.yml" + "https://ghe.mycorp.local/myorg/repo/raw/v1/action.yml", + "https://avatars.ghe.mycorp.local/u/1234", + "https://media.ghe.mycorp.local/user/1234/files/abc123" ]) - fun `given GHE server, main and raw subdomain URLs are accepted`(url: String) { + fun `given GHE server, its main, raw, avatars and media subdomain URLs are accepted`(url: String) { val sp = serverPath("ghe.mycorp.local") assertTrue(GithubApiRequestExecutor.isAuthorizedUrl(sp, URL(url))) } @@ -104,7 +106,9 @@ class GithubApiRequestExecutorAuthTest { "https://raw.ghe.mycorp.local.malicious.com/org/repo/file", "https://raw.ghe.mycorp.malicious.local/org/repo/file", "https://raw.ghe.malicious.mycorp.local.com/org/repo/file", - "https://raw.malicious.ghe.mycorp.local.com/org/repo/file" + "https://raw.malicious.ghe.mycorp.local.com/org/repo/file", + "https://avatars.ghe.mycorp.local.malicious.com/u/1234", + "https://media.ghe.mycorp.local.malicious.com/user/1234/files/abc" ]) fun `malicious hosts for GHE are rejected`(url: String) { val spEnterprise = serverPath("ghe.mycorp.local")