diff --git a/src/Cli/dotnet/CliStrings.resx b/src/Cli/dotnet/CliStrings.resx
index 7b118637944b..211be41cbab6 100644
--- a/src/Cli/dotnet/CliStrings.resx
+++ b/src/Cli/dotnet/CliStrings.resx
@@ -838,4 +838,7 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is
Only one .nuspec file can be packed at a time
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
\ No newline at end of file
diff --git a/src/Cli/dotnet/Commands/Tool/Install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/Commands/Tool/Install/ToolInstallGlobalOrToolPathCommand.cs
index 0a23fad43910..c465e20372e5 100644
--- a/src/Cli/dotnet/Commands/Tool/Install/ToolInstallGlobalOrToolPathCommand.cs
+++ b/src/Cli/dotnet/Commands/Tool/Install/ToolInstallGlobalOrToolPathCommand.cs
@@ -96,7 +96,22 @@ public ToolInstallGlobalOrToolPathCommand(
NoCache: parseResult.GetValue(ToolCommandRestorePassThroughOptions.NoCacheOption) || parseResult.GetValue(ToolCommandRestorePassThroughOptions.NoHttpCacheOption),
IgnoreFailedSources: parseResult.GetValue(ToolCommandRestorePassThroughOptions.IgnoreFailedSourcesOption),
Interactive: parseResult.GetValue(ToolCommandRestorePassThroughOptions.InteractiveRestoreOption));
- nugetPackageDownloader ??= new NuGetPackageDownloader.NuGetPackageDownloader(tempDir, verboseLogger: new NullLogger(), restoreActionConfig: restoreActionConfig, verbosityOptions: _verbosity, verifySignatures: verifySignatures ?? true);
+ nugetPackageDownloader ??= new NuGetPackageDownloader.NuGetPackageDownloader(tempDir, verboseLogger: new NullLogger(), restoreActionConfig: restoreActionConfig, verbosityOptions: _verbosity, verifySignatures: verifySignatures ?? true, shouldUsePackageSourceMapping: true, currentWorkingDirectory: _currentWorkingDirectory);
+
+ // Perform HTTP source validation early to ensure compatibility with .NET 9 requirements
+ if (_packageId != null)
+ {
+ var packageSourceLocationForValidation = new PackageSourceLocation(
+ nugetConfig: GetConfigFile(),
+ additionalSourceFeeds: _addSource,
+ basePath: _currentWorkingDirectory);
+
+ if (nugetPackageDownloader is NuGetPackageDownloader.NuGetPackageDownloader concreteDownloader)
+ {
+ concreteDownloader.LoadNuGetSources((PackageId)_packageId, packageSourceLocationForValidation);
+ }
+ }
+
_shellShimTemplateFinder = new ShellShimTemplateFinder(nugetPackageDownloader, tempDir, packageSourceLocation);
_store = store;
diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs
index 8ac89af40212..a311e88c646d 100644
--- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs
+++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs
@@ -4,9 +4,11 @@
#nullable disable
using System.Collections.Concurrent;
+using Microsoft.DotNet.Cli.Extensions;
using Microsoft.DotNet.Cli.NugetPackageDownloader;
using Microsoft.DotNet.Cli.ToolPackage;
using Microsoft.DotNet.Cli.Utils;
+using Microsoft.DotNet.Cli.Utils.Extensions;
using Microsoft.Extensions.EnvironmentAbstractions;
using NuGet.Common;
using NuGet.Configuration;
@@ -450,9 +452,21 @@ public IEnumerable LoadNuGetSources(PackageId packageId, PackageS
throw new NuGetPackageInstallerException("No NuGet sources are defined or enabled");
}
+ CheckHttpSources(sources);
return sources;
}
+ private void CheckHttpSources(IEnumerable packageSources)
+ {
+ foreach (var packageSource in packageSources)
+ {
+ if (packageSource.IsHttp && !packageSource.IsHttps && !packageSource.AllowInsecureConnections)
+ {
+ throw new NuGetPackageInstallerException(string.Format(CliStrings.Error_NU1302_HttpSourceUsed, packageSource.Source));
+ }
+ }
+ }
+
private async Task<(PackageSource, IPackageSearchMetadata)> GetMatchingVersionInternalAsync(
string packageIdentifier, IEnumerable packageSources, VersionRange versionRange,
CancellationToken cancellationToken)
diff --git a/src/Cli/dotnet/xlf/CliStrings.cs.xlf b/src/Cli/dotnet/xlf/CliStrings.cs.xlf
index 8c5278436280..4055bdd0669b 100644
--- a/src/Cli/dotnet/xlf/CliStrings.cs.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.cs.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
Chyba
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0}: Soubor deps.json se očekává v: {1}
diff --git a/src/Cli/dotnet/xlf/CliStrings.de.xlf b/src/Cli/dotnet/xlf/CliStrings.de.xlf
index 491f30dc0ea6..328ee1eaf90c 100644
--- a/src/Cli/dotnet/xlf/CliStrings.de.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.de.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
Fehler
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0}: "deps.json" vermutet unter: {1}
diff --git a/src/Cli/dotnet/xlf/CliStrings.es.xlf b/src/Cli/dotnet/xlf/CliStrings.es.xlf
index 5b0099211e6a..3e18dfbbf79b 100644
--- a/src/Cli/dotnet/xlf/CliStrings.es.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.es.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
Error
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0}: se espera deps.json en: {1}
diff --git a/src/Cli/dotnet/xlf/CliStrings.fr.xlf b/src/Cli/dotnet/xlf/CliStrings.fr.xlf
index 4ee023051432..1f111b778d8b 100644
--- a/src/Cli/dotnet/xlf/CliStrings.fr.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.fr.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
Erreur
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0} : deps.json attendu sur {1}
diff --git a/src/Cli/dotnet/xlf/CliStrings.it.xlf b/src/Cli/dotnet/xlf/CliStrings.it.xlf
index 25f463a93e09..37126bfb6668 100644
--- a/src/Cli/dotnet/xlf/CliStrings.it.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.it.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
Errore
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0}: è previsto deps.json in: {1}
diff --git a/src/Cli/dotnet/xlf/CliStrings.ja.xlf b/src/Cli/dotnet/xlf/CliStrings.ja.xlf
index 929c69303fce..d6319a00890a 100644
--- a/src/Cli/dotnet/xlf/CliStrings.ja.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.ja.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
エラー
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0}: {1} で deps.json が必要です
diff --git a/src/Cli/dotnet/xlf/CliStrings.ko.xlf b/src/Cli/dotnet/xlf/CliStrings.ko.xlf
index 70f1a461e3ec..e327f2d9959b 100644
--- a/src/Cli/dotnet/xlf/CliStrings.ko.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.ko.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
오류
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0}: {1}에서 deps.json 필요
diff --git a/src/Cli/dotnet/xlf/CliStrings.pl.xlf b/src/Cli/dotnet/xlf/CliStrings.pl.xlf
index ab822597d6bb..51111e6a5f72 100644
--- a/src/Cli/dotnet/xlf/CliStrings.pl.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.pl.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
Błąd
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0}: Oczekiwano pliku deps.json w lokalizacji: {1}
diff --git a/src/Cli/dotnet/xlf/CliStrings.pt-BR.xlf b/src/Cli/dotnet/xlf/CliStrings.pt-BR.xlf
index 1fb89af5253a..9f9cc1e2b31b 100644
--- a/src/Cli/dotnet/xlf/CliStrings.pt-BR.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.pt-BR.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
Erro
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0}: espera de deps.json em: {1}
diff --git a/src/Cli/dotnet/xlf/CliStrings.ru.xlf b/src/Cli/dotnet/xlf/CliStrings.ru.xlf
index 73edbd77fffd..91eed74c2418 100644
--- a/src/Cli/dotnet/xlf/CliStrings.ru.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.ru.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
Ошибка
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0}: ожидается deps.json в: {1}.
diff --git a/src/Cli/dotnet/xlf/CliStrings.tr.xlf b/src/Cli/dotnet/xlf/CliStrings.tr.xlf
index 162ee49cbd83..6da85f30a3db 100644
--- a/src/Cli/dotnet/xlf/CliStrings.tr.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.tr.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
Hata
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0}: şu konumda deps.json bekleniyor: {1}
diff --git a/src/Cli/dotnet/xlf/CliStrings.zh-Hans.xlf b/src/Cli/dotnet/xlf/CliStrings.zh-Hans.xlf
index d32b2f7bcba0..14961ca1ea30 100644
--- a/src/Cli/dotnet/xlf/CliStrings.zh-Hans.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.zh-Hans.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
错误
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0}: 需要 deps.json: {1}
diff --git a/src/Cli/dotnet/xlf/CliStrings.zh-Hant.xlf b/src/Cli/dotnet/xlf/CliStrings.zh-Hant.xlf
index 0009d535cc37..75aa1bf0f290 100644
--- a/src/Cli/dotnet/xlf/CliStrings.zh-Hant.xlf
+++ b/src/Cli/dotnet/xlf/CliStrings.zh-Hant.xlf
@@ -372,6 +372,11 @@ setx PATH "%PATH%;{0}"
錯誤
+
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+ You are running the 'tool install' operation with an 'HTTP' source: {0}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Refer to https://aka.ms/nuget-https-everywhere for more information.
+
+ {0}: expect deps.json at: {1}{0}: 於 {1} 需要 deps.json
diff --git a/test/dotnet.Tests/CommandTests/Tool/Install/ToolInstallGlobalOrToolPathCommandTests.cs b/test/dotnet.Tests/CommandTests/Tool/Install/ToolInstallGlobalOrToolPathCommandTests.cs
index ea127f2fbba0..0d80b9d9d133 100644
--- a/test/dotnet.Tests/CommandTests/Tool/Install/ToolInstallGlobalOrToolPathCommandTests.cs
+++ b/test/dotnet.Tests/CommandTests/Tool/Install/ToolInstallGlobalOrToolPathCommandTests.cs
@@ -197,7 +197,7 @@ public void WhenRunWithSourceItShouldFindOnlyTheProvidedSource()
[Fact]
public void WhenRunWithPackageIdWithSourceItShouldCreateValidShim()
{
- const string sourcePath = "http://mysource.com";
+ const string sourcePath = "https://mysource.com";
ParseResult result = Parser.Parse($"dotnet tool install -g {PackageId} --add-source {sourcePath}");
var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand(
@@ -666,7 +666,6 @@ public void WhenRunWithoutValidVersionUnlistedToolItShouldThrow()
var testDir = _testAssetsManager.CreateTestDirectory().Path;
var toolInstallGlobalOrToolPathCommand = new DotnetCommand(Log, "tool", "install", "-g", UnlistedPackageId, "--add-source", nugetSourcePath)
- .WithEnvironmentVariable("DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK", "true")
.WithWorkingDirectory(testDir);
toolInstallGlobalOrToolPathCommand.Execute().Should().Fail();
@@ -928,6 +927,78 @@ public void WhenRunWithArchOptionItDownloadsAppHostTemplate()
nugetPackageDownloader.DownloadCallParams.First().Item1.Should().Be(new PackageId("microsoft.netcore.app.host.win-arm64"));
}
+ [Fact]
+ public void WhenRunWithHttpSourceViaAddSourceItShouldShowNU1302Error()
+ {
+ var testDir = _testAssetsManager.CreateTestDirectory().Path;
+
+ var toolInstallCommand = new DotnetCommand(Log, "tool", "install", "-g", "fake-tool", "--add-source", "http://test.example.com/nuget")
+ .WithWorkingDirectory(testDir);
+
+ var result = toolInstallCommand.Execute();
+
+ result.Should().Fail();
+ result.StdErr.Should().Contain("You are running the 'tool install' operation with an 'HTTP' source: http://test.example.com/nuget");
+ result.StdErr.Should().Contain("NuGet requires HTTPS sources");
+ result.StdErr.Should().Contain("allowInsecureConnections");
+ }
+
+ [Fact]
+ public void WhenRunWithHttpSourceInNuGetConfigItShouldShowNU1302Error()
+ {
+ var testDir = _testAssetsManager.CreateTestDirectory().Path;
+ var nugetConfigPath = Path.Combine(testDir, "nuget.config");
+
+ var nugetConfigContent = @"
+
+
+
+
+
+";
+
+ File.WriteAllText(nugetConfigPath, nugetConfigContent);
+
+ var toolInstallCommand = new DotnetCommand(Log, "tool", "install", "-g", "fake-tool")
+ .WithWorkingDirectory(testDir);
+
+ var result = toolInstallCommand.Execute();
+
+ result.Should().Fail();
+ result.StdErr.Should().Contain("You are running the 'tool install' operation with an 'HTTP' source: http://test.example.com/nuget");
+ result.StdErr.Should().Contain("NuGet requires HTTPS sources");
+ result.StdErr.Should().Contain("allowInsecureConnections");
+ }
+
+ [Fact]
+ public void WhenRunWithHttpSourceAndAllowInsecureConnectionsItShouldSucceed()
+ {
+ var testDir = _testAssetsManager.CreateTestDirectory().Path;
+ var nugetConfigPath = Path.Combine(testDir, "nuget.config");
+
+ var nugetConfigContent = @"
+
+
+
+
+
+";
+
+ File.WriteAllText(nugetConfigPath, nugetConfigContent);
+
+ var toolInstallCommand = new DotnetCommand(Log, "tool", "install", "-g", "fake-tool")
+ .WithWorkingDirectory(testDir);
+
+ var result = toolInstallCommand.Execute();
+
+ // Should fail for other reasons (unable to load service index) but not due to HTTP source validation
+ result.Should().Fail();
+ result.StdErr.Should().NotContain("You are running the 'tool install' operation with an 'HTTP' source:");
+ result.StdErr.Should().NotContain("NuGet requires HTTPS sources");
+ // Should fail because the service index can't be loaded, not because of HTTP validation
+ result.StdErr.Should().Contain("Unable to load the service index");
+ }
+
private string ExpectedCommandPath()
{
var extension = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty;