{"record":{"id":"58bb91a1f9d1613f","repo":"git-ecosystem/git-credential-manager","slug":"unencrypted-http-is-not-recommended-for-bitbucket","errorCode":null,"errorMessage":"Unencrypted HTTP is not recommended for Bitbucket.org. Ensure the repository remote URL is using HTTPS or see https://aka.ms/gcm/unsafe-remotes about how to allow unsafe remotes.","messagePattern":"Unencrypted HTTP is not recommended for Bitbucket\\.org\\. Ensure the repository remote URL is using HTTPS or see https://aka\\.ms/gcm/unsafe-remotes about how to allow unsafe remotes\\.","errorType":"exception","errorClass":"Trace2Exception","httpStatus":null,"severity":"error","filePath":"src/Atlassian.Bitbucket/BitbucketHostProvider.cs","lineNumber":94,"sourceCode":"                return false;\n            }\n\n            // Identify Bitbucket on-prem instances from the HTTP response using the Atlassian specific header X-AREQUESTID\n            var supported = response.Headers.Contains(\"X-AREQUESTID\");\n\n            _context.Trace.WriteLine($\"Host is{(supported ? null : \"n't\")} supported as Bitbucket\");\n\n            return supported;\n        }\n\n        public async Task<GitResponse> GetCredentialAsync(GitRequest request)\n        {\n            // We should not allow unencrypted communication and should inform the user\n            if (!_context.Settings.AllowUnsafeRemotes &&\n                StringComparer.OrdinalIgnoreCase.Equals(request.Protocol, \"http\") &&\n                BitbucketHelper.IsBitbucketOrg(request))\n            {\n                throw new Trace2Exception(_context.Trace2,\n                    \"Unencrypted HTTP is not recommended for Bitbucket.org. \" +\n                    \"Ensure the repository remote URL is using HTTPS \" +\n                    $\"or see {Constants.HelpUrls.GcmUnsafeRemotes} about how to allow unsafe remotes.\");\n            }\n\n            var authModes = await GetSupportedAuthenticationModesAsync(request);\n\n            ICredential credential = await GetStoredCredentials(request, authModes) ??\n                                     await GetRefreshedCredentials(request, authModes);\n            return new GitResponse(credential);\n        }\n\n        private async Task<ICredential> GetStoredCredentials(GitRequest request, AuthenticationModes authModes)\n        {\n            if (_context.Settings.TryGetSetting(BitbucketConstants.EnvironmentVariables.AlwaysRefreshCredentials,\n                Constants.GitConfiguration.Credential.SectionName, BitbucketConstants.GitConfiguration.Credential.AlwaysRefreshCredentials,\n                out string alwaysRefreshCredentials) && alwaysRefreshCredentials.ToBooleanyOrDefault(false))\n            {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/Atlassian.Bitbucket/BitbucketHostProvider.cs#L76-L112","documentation":"BitbucketHostProvider.GetCredentialAsync refuses to send credentials over unencrypted HTTP to bitbucket.org. If AllowUnsafeRemotes is disabled (default) and the request targets http://bitbucket.org, a Trace2Exception is thrown advising HTTPS or opting into unsafe remotes. This protects tokens from plaintext transmission.","triggerScenarios":"git remote URL uses http:// for bitbucket.org (e.g. http://bitbucket.org/user/repo.git) while GCM_BITBUCKET_DEVSETTINGS / AllowUnsafeRemotes is false (default).","commonSituations":"Cloning with http:// by mistake; internal mirrors rewriting URLs to http; old scripts using http endpoints against bitbucket.org.","solutions":["Change the remote to HTTPS: git remote set-url origin https://bitbucket.org/user/repo.git","If truly required, opt in via `git config --global credential.allowUnsafeRemotes true` (see https://aka.ms/gcm/unsafe-remotes)","Update documentation/scripts/CI that clone from the http:// URL"],"exampleFix":"// before\nurl = \"http://bitbucket.org/user/repo.git\";\n// after\nurl = \"https://bitbucket.org/user/repo.git\";","handlingStrategy":"validation","validationCode":"var uri = new Uri(remoteUrl);\nbool unsafeBitbucket = uri.Scheme == Uri.UriSchemeHttp && uri.Host.Equals(\"bitbucket.org\", StringComparison.OrdinalIgnoreCase);\nif (unsafeBitbucket && !allowUnsafeRemotes) throw new InvalidOperationException(\"Switch remote to HTTPS\");","typeGuard":"bool IsHttpsRemote(Uri u) => u.Scheme == Uri.UriSchemeHttps;","tryCatchPattern":"try { await provider.GetCredentialAsync(input); }\ncatch (Trace2Exception ex) when (ex.Message.Contains(\"Unencrypted HTTP\")) { /* rewrite remote to https and retry */ }","preventionTips":["Always use https:// remotes for bitbucket.org","Audit CI scripts and docs for http:// clone URLs","Only enable credential.allowUnsafeRemotes for trusted internal hosts, never bitbucket.org"],"tags":["security","http","https","bitbucket","remote-url"],"backgroundTag":"unsupported-operation","analyzedSha":"e8ce762cd04b4100ae637b5fbf39ef9d0a96561e","analyzedAt":"2026-09-11T17:15:08.753Z","contentChangedAt":"2026-09-11T17:15:08.753Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}