diff --git a/Duplicati/Server/Database/Backup.cs b/Duplicati/Server/Database/Backup.cs index efc74bfc3..3f38fd8fc 100644 --- a/Duplicati/Server/Database/Backup.cs +++ b/Duplicati/Server/Database/Backup.cs @@ -19,12 +19,27 @@ using System; using Duplicati.Server.Serialization.Interface; using System.Collections.Generic; using System.Text.RegularExpressions; +using System.Linq; namespace Duplicati.Server.Database { public class Backup : IBackup - { - + { + // Sensitive information that may be stored in TargetUrl + private readonly string[] UrlPasswords = new[]{ + "authid", + "auth-password", + "sia-password", + }; + + // Sensitive information that may be stored in Settings + private readonly string[] SettingPasswords = new[]{ + "passphrase", + "--authid", + "--send-mail-password", + "--send-xmpp-password" + }; + public Backup() { this.ID = null; @@ -100,24 +115,25 @@ namespace Duplicati.Server.Database public bool IsTemporary { get { return ID == null ? false : ID.IndexOf("-", StringComparison.Ordinal) > 0; } } /// - /// Sanitizes the backup TargetUrl + /// Sanitizes the backup TargetUrl from any fields in the PasswordFields list. /// public void SanitizeTargetUrl() { - var url = this.TargetURL; - // Remove authid - url = Regex.Replace(url, "authid=[^&\n]+[&]?", ""); - // remove auth-password - url = Regex.Replace(url, "auth-password=[^&\n]+[&]?", ""); - // remove backupsia-password - url = Regex.Replace(url, "sia-password=[^&\n]+[&]?", ""); - // Remove edge case of '?&' - url = Regex.Replace(url, Regex.Escape("?&"), ""); - // Remove edge case of '&' at end of line - url = Regex.Replace(url, "&$", ""); - // Remove edge case of '?' at end of line - url = Regex.Replace(url, Regex.Escape("?") + "$", ""); - this.TargetURL = url; + var url = new Duplicati.Library.Utility.Uri(this.TargetURL); + var filteredParameters = url.QueryParameters; + foreach (string field in UrlPasswords) { + filteredParameters.Remove(field); + } + url = url.SetQuery(Duplicati.Library.Utility.Uri.BuildUriQuery(url.QueryParameters)); + this.TargetURL = url.ToString(); + } + + /// + /// Sanitizes the settings from any fields in the PassworldFields list. + /// + public void SanitizeSettings() + { + this.Settings = this.Settings.Where((setting) => !SettingPasswords.Contains(setting.Name)).ToArray(); } } } diff --git a/Duplicati/Server/Duplicati.Server.Serialization/Interface/IBackup.cs b/Duplicati/Server/Duplicati.Server.Serialization/Interface/IBackup.cs index 1330332d6..9b2f59c76 100644 --- a/Duplicati/Server/Duplicati.Server.Serialization/Interface/IBackup.cs +++ b/Duplicati/Server/Duplicati.Server.Serialization/Interface/IBackup.cs @@ -76,6 +76,8 @@ namespace Duplicati.Server.Serialization.Interface bool IsTemporary { get; } void SanitizeTargetUrl(); + + void SanitizeSettings(); } } diff --git a/Duplicati/Server/WebServer/RESTMethods/Backup.cs b/Duplicati/Server/WebServer/RESTMethods/Backup.cs index 7ad204990..e1057982b 100644 --- a/Duplicati/Server/WebServer/RESTMethods/Backup.cs +++ b/Duplicati/Server/WebServer/RESTMethods/Backup.cs @@ -121,10 +121,9 @@ namespace Duplicati.Server.WebServer.RESTMethods var cmdline = Library.Utility.Utility.ParseBool(info.Request.QueryString["cmdline"].Value, false); var argsonly = Library.Utility.Utility.ParseBool(info.Request.QueryString["argsonly"].Value, false); var exportPasswords = Library.Utility.Utility.ParseBool(info.Request.QueryString["export-passwords"].Value, false); - var passwordFields = new [] { "passphrase", "--send-mail-password", "--send-xmpp-password" }; if (!exportPasswords) { - backup.Settings = (Duplicati.Server.Serialization.Interface.ISetting[])backup.Settings.Where((setting) => !passwordFields.Contains(setting.Name)).ToArray(); + backup.SanitizeSettings(); backup.SanitizeTargetUrl(); }