diff --git a/Duplicati/Library/Backend/S3/S3Backend.cs b/Duplicati/Library/Backend/S3/S3Backend.cs index 262a8433d..849e8b5da 100644 --- a/Duplicati/Library/Backend/S3/S3Backend.cs +++ b/Duplicati/Library/Backend/S3/S3Backend.cs @@ -247,6 +247,10 @@ namespace Duplicati.Library.Backend if (!options.ContainsKey("s3-ext-forcepathstyle") && !hostname.EndsWith(".amazonaws.com", StringComparison.OrdinalIgnoreCase)) options["s3-ext-forcepathstyle"] = "true"; + // Validate that hostname doesn't contain a path + if (hostname.Contains('/') || hostname.Contains('\\')) + throw new UserInformationException(Strings.S3Backend.NoPathAllowedInEndpointError, "S3NoPathInEndpoint"); + var s3ClientOptionValue = options.GetValueOrDefault(S3_CLIENT_OPTION); diff --git a/Duplicati/Library/Backend/S3/Strings.cs b/Duplicati/Library/Backend/S3/Strings.cs index fc77f6ec6..61627d335 100644 --- a/Duplicati/Library/Backend/S3/Strings.cs +++ b/Duplicati/Library/Backend/S3/Strings.cs @@ -58,6 +58,7 @@ namespace Duplicati.Library.Backend.Strings public static string DescriptionRecursiveListShort { get { return LC.L(@"Use this option to list all files in the bucket"); } } public static string DescriptionRecursiveListLong { get { return LC.L(@"To reduce the number of objects listed, the default is to only list the first level of objects. Use this option to list all objects in the bucket."); } } public static string UnknownS3ClientError(string client) { return LC.L(@"Unknown S3 client: {0}", client); } + public static string NoPathAllowedInEndpointError { get { return LC.L(@"No path allowed in endpoint"); } } } internal static class S3Config