diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs index 4b3484936f..1827305353 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs @@ -371,7 +371,7 @@ public class NpmPackagesUpdater : ITransientDependency } else { - Logger.LogWarning($"Skipping invalid npm package name: {p.Name}"); + Logger.LogWarning($"Skipping invalid npm package name: {NpmHelper.SanitizeForLog(p.Name)}"); } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs index aa61122128..8e8d52f7be 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs @@ -73,6 +73,7 @@ public class ProjectNpmPackageAdder : ITransientDependency } NpmHelper.EnsureSafePackageName(npmPackage.Name); + NpmHelper.EnsureSafeVersion(version); Logger.LogInformation($"Installing '{npmPackage.Name}' package to the project '{packageJsonFilePath}'..."); @@ -148,6 +149,8 @@ public class ProjectNpmPackageAdder : ITransientDependency version = DetectAbpVersionOrNull(Path.Combine(directory, "package.json")); } + NpmHelper.EnsureSafeVersion(version); + var versionPostfix = version != null ? $"@{version}" : string.Empty; using (DirectoryHelper.ChangeCurrentDirectory(directory)) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/NpmHelper.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/NpmHelper.cs index 8684360f4d..13069c6ae1 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/NpmHelper.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/NpmHelper.cs @@ -67,6 +67,7 @@ public class NpmHelper : ITransientDependency public void NpmInstallPackage(string package, string version, string directory) { EnsureSafePackageName(package); + EnsureSafeVersion(version); var packageVersion = !string.IsNullOrWhiteSpace(version) ? $"@{version}" : string.Empty; CmdHelper.RunCmd("npm install --ignore-scripts " + package + packageVersion, workingDirectory: directory); } @@ -74,6 +75,7 @@ public class NpmHelper : ITransientDependency public void YarnAddPackage(string package, string version, string directory) { EnsureSafePackageName(package); + EnsureSafeVersion(version); var packageVersion = !string.IsNullOrWhiteSpace(version) ? $"@{version}" : string.Empty; CmdHelper.RunCmd("npx yarn add " + package + packageVersion + " --ignore-scripts", workingDirectory: directory); } @@ -82,14 +84,31 @@ public class NpmHelper : ITransientDependency @"^(@[a-zA-Z0-9][a-zA-Z0-9._-]*/)?[a-zA-Z0-9][a-zA-Z0-9._-]*$", RegexOptions.Compiled); + private static readonly Regex SafeVersionRegex = new( + @"^[a-zA-Z0-9._~^><=|\-+]+$", + RegexOptions.Compiled); + public static void EnsureSafePackageName(string packageName) { if (!SafePackageNameRegex.IsMatch(packageName)) { - throw new InvalidOperationException($"Invalid npm package name detected: {packageName}"); + throw new CliUsageException($"Invalid npm package name detected: {SanitizeForLog(packageName)}"); + } + } + + public static void EnsureSafeVersion(string version) + { + if (!string.IsNullOrWhiteSpace(version) && !SafeVersionRegex.IsMatch(version)) + { + throw new CliUsageException($"Invalid npm package version detected: {SanitizeForLog(version)}"); } } + public static string SanitizeForLog(string value) + { + return Regex.Replace(value, @"[\x00-\x1F\x7F]", "?"); + } + public string GetInstalledNpmPackages() { Logger.LogInformation("Checking installed npm global packages...");