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();
}