From 3999f735a712b59d5d0047d48cc65bbc0cd9ffec Mon Sep 17 00:00:00 2001
From: Mira <56395159+TheXorog@users.noreply.github.com>
Date: Thu, 16 May 2024 22:20:44 +0200
Subject: [PATCH 1/8] feat: Add StripTokens
Co-authored-by: quinchs <>
---
DisCatSharp/Utilities.cs | 57 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/DisCatSharp/Utilities.cs b/DisCatSharp/Utilities.cs
index 67f2a6bb64..21ea99d810 100644
--- a/DisCatSharp/Utilities.cs
+++ b/DisCatSharp/Utilities.cs
@@ -90,6 +90,63 @@ static Utilities()
VersionHeader = $"DiscordBot (https://github.com/Aiko-IT-Systems/DisCatSharp, v{vs})";
}
+
+
+ ///
+ /// Removes discord-based tokens from a given string.
+ ///
+ /// The string to remove the tokens from.
+ /// A new string with the tokens replaced with {KEY_TOKEN}
+ public static string StripTokens(string str)
+ {
+ if (string.IsNullOrWhiteSpace(str))
+ return str;
+
+ var parts = str.Split('/');
+
+ // calculate the base64 data size
+ var base64Size = parts.Max(x =>
+ {
+ var padding = x.EndsWith("==", StringComparison.Ordinal)
+ ? 2
+ : x.EndsWith("=", StringComparison.Ordinal)
+ ? 1
+ : 0;
+ return (Encoding.UTF8.GetByteCount(x) * (3 / 4)) - padding;
+ });
+
+ // allocate a buffer for any base64 decoding.
+ var dest = base64Size <= 1024 ? stackalloc byte[base64Size] : new byte[base64Size];
+
+ var isWebhook = parts.Contains("webhooks") || parts.Contains("webhook");
+
+ for (var i = 0; i < parts.Length; i++)
+ {
+ var part = parts[i];
+
+ if (isWebhook && Regex.IsMatch(part, @"([a-zA-Z0-9]{68})"))
+ {
+ parts[i] = "{WEBHOOK_TOKEN}";
+ continue;
+ }
+
+ if (!Convert.TryFromBase64String(part, dest, out var count))
+ continue;
+
+ var b64Content = Encoding.UTF8.GetString(dest[..count]);
+
+ var tokenInnersMatch = Regex.Match(b64Content, @"^(.+):\d+?:[a-zA-Z0-9]{128}$");
+
+ if (!tokenInnersMatch.Success)
+ continue;
+
+ // replaces the token with the {KEY}_TOKEN, ex 'interaction:USERID:TOKEN' is replaced as 'INTERACTION_TOKEN'
+ parts[i] = $"{{{tokenInnersMatch.Groups[1].Value.ToUpperInvariant()}_TOKEN}}";
+ }
+
+ return string.Join('/', parts);
+ }
+
///
/// Adds the specified parameter to the Query String.
///
From 6e95e8c82797c715f42076883c02179c083aace2 Mon Sep 17 00:00:00 2001
From: Mira <56395159+TheXorog@users.noreply.github.com>
Date: Thu, 16 May 2024 22:24:21 +0200
Subject: [PATCH 2/8] add breadcrumb filter
---
DisCatSharp/Clients/BaseDiscordClient.cs | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/DisCatSharp/Clients/BaseDiscordClient.cs b/DisCatSharp/Clients/BaseDiscordClient.cs
index 25b00bfde0..e7d4bc0452 100644
--- a/DisCatSharp/Clients/BaseDiscordClient.cs
+++ b/DisCatSharp/Clients/BaseDiscordClient.cs
@@ -249,6 +249,15 @@ protected BaseDiscordClient(DiscordConfiguration config)
EnableScopeSync = true,
Debug = this.Configuration.SentryDebug
};
+
+ options.SetBeforeBreadcrumb(b
+ => new Breadcrumb(Utilities.StripTokens(b.Message),
+ b.Type,
+ b.Data?.Select(x => new KeyValuePair(x.Key, Utilities.StripTokens(x.Value)))
+ .ToDictionary(x => x.Key, x => x.Value),
+ b.Category,
+ b.Level));
+
options.SetBeforeSend((e, _) =>
{
if (!this.Configuration.DisableExceptionFilter)
From 22a4ce97a478b46798efeb5edf8add013cb3536a Mon Sep 17 00:00:00 2001
From: Mira <56395159+TheXorog@users.noreply.github.com>
Date: Thu, 16 May 2024 22:37:49 +0200
Subject: [PATCH 3/8] add before transaction filter
---
DisCatSharp/Clients/BaseDiscordClient.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/DisCatSharp/Clients/BaseDiscordClient.cs b/DisCatSharp/Clients/BaseDiscordClient.cs
index e7d4bc0452..d0f3525782 100644
--- a/DisCatSharp/Clients/BaseDiscordClient.cs
+++ b/DisCatSharp/Clients/BaseDiscordClient.cs
@@ -258,6 +258,14 @@ protected BaseDiscordClient(DiscordConfiguration config)
b.Category,
b.Level));
+ options.SetBeforeSendTransaction(tr =>
+ {
+ if (tr.Request.Data is string str)
+ tr.Request.Data = Utilities.StripTokens(str);
+
+ return tr;
+ });
+
options.SetBeforeSend((e, _) =>
{
if (!this.Configuration.DisableExceptionFilter)
From ab6c303f2ae873c9751fb3cbab13f1ded44e8faf Mon Sep 17 00:00:00 2001
From: Mira <56395159+TheXorog@users.noreply.github.com>
Date: Thu, 16 May 2024 23:41:55 +0200
Subject: [PATCH 4/8] simplify implementation + and actually make it work in
this use case
---
DisCatSharp/Utilities.cs | 48 +++++-----------------------------------
1 file changed, 5 insertions(+), 43 deletions(-)
diff --git a/DisCatSharp/Utilities.cs b/DisCatSharp/Utilities.cs
index 21ea99d810..0b7810b9f9 100644
--- a/DisCatSharp/Utilities.cs
+++ b/DisCatSharp/Utilities.cs
@@ -97,54 +97,16 @@ static Utilities()
///
/// The string to remove the tokens from.
/// A new string with the tokens replaced with {KEY_TOKEN}
- public static string StripTokens(string str)
+ public static string? StripTokens(string? str)
{
if (string.IsNullOrWhiteSpace(str))
return str;
- var parts = str.Split('/');
+ str = Regex.Replace(str, @"([a-zA-Z0-9]{68})", "{WEBHOOK_TOKEN}");
+ str = Regex.Replace(str, @"^(.+):\d+?:[a-zA-Z0-9]{128}$", "{INTERACTION_TOKEN}");
+ str = Regex.Replace(str, @"(mfa\.[a-z0-9_-]{20,})|((?[a-z0-9_-]{23,28})\.(?[a-z0-9_-]{6,7})\.(?[a-z0-9_-]{27,}))", "{ACCOUNT_TOKEN}");
- // calculate the base64 data size
- var base64Size = parts.Max(x =>
- {
- var padding = x.EndsWith("==", StringComparison.Ordinal)
- ? 2
- : x.EndsWith("=", StringComparison.Ordinal)
- ? 1
- : 0;
- return (Encoding.UTF8.GetByteCount(x) * (3 / 4)) - padding;
- });
-
- // allocate a buffer for any base64 decoding.
- var dest = base64Size <= 1024 ? stackalloc byte[base64Size] : new byte[base64Size];
-
- var isWebhook = parts.Contains("webhooks") || parts.Contains("webhook");
-
- for (var i = 0; i < parts.Length; i++)
- {
- var part = parts[i];
-
- if (isWebhook && Regex.IsMatch(part, @"([a-zA-Z0-9]{68})"))
- {
- parts[i] = "{WEBHOOK_TOKEN}";
- continue;
- }
-
- if (!Convert.TryFromBase64String(part, dest, out var count))
- continue;
-
- var b64Content = Encoding.UTF8.GetString(dest[..count]);
-
- var tokenInnersMatch = Regex.Match(b64Content, @"^(.+):\d+?:[a-zA-Z0-9]{128}$");
-
- if (!tokenInnersMatch.Success)
- continue;
-
- // replaces the token with the {KEY}_TOKEN, ex 'interaction:USERID:TOKEN' is replaced as 'INTERACTION_TOKEN'
- parts[i] = $"{{{tokenInnersMatch.Groups[1].Value.ToUpperInvariant()}_TOKEN}}";
- }
-
- return string.Join('/', parts);
+ return str;
}
///
From 4e4f0183054448277929a4a7d66cea01e3335203 Mon Sep 17 00:00:00 2001
From: Mira <56395159+TheXorog@users.noreply.github.com>
Date: Fri, 17 May 2024 16:14:58 +0200
Subject: [PATCH 5/8] fix regex to actually match tokens & simplify
Co-authored-by: quinchs <49576606+quinchs@users.noreply.github.com>
---
DisCatSharp/Utilities.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/DisCatSharp/Utilities.cs b/DisCatSharp/Utilities.cs
index 0b7810b9f9..2860e9a6be 100644
--- a/DisCatSharp/Utilities.cs
+++ b/DisCatSharp/Utilities.cs
@@ -102,8 +102,7 @@ static Utilities()
if (string.IsNullOrWhiteSpace(str))
return str;
- str = Regex.Replace(str, @"([a-zA-Z0-9]{68})", "{WEBHOOK_TOKEN}");
- str = Regex.Replace(str, @"^(.+):\d+?:[a-zA-Z0-9]{128}$", "{INTERACTION_TOKEN}");
+ str = Regex.Replace(str, @"([a-zA-Z0-9]{68,})", "{WEBHOOK_OR_INTERACTION_TOKEN}"); // Any alphanumeric string this long is likely to be sensitive information anyways
str = Regex.Replace(str, @"(mfa\.[a-z0-9_-]{20,})|((?[a-z0-9_-]{23,28})\.(?[a-z0-9_-]{6,7})\.(?[a-z0-9_-]{27,}))", "{ACCOUNT_TOKEN}");
return str;
From 37e408bbe52df6ea45bff63ecd0c02cf0a042ad1 Mon Sep 17 00:00:00 2001
From: Lala Sabathil
Date: Sun, 19 May 2024 07:38:36 +0200
Subject: [PATCH 6/8] Update DisCatSharp/Utilities.cs
Signed-off-by: Lala Sabathil
---
DisCatSharp/Utilities.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/DisCatSharp/Utilities.cs b/DisCatSharp/Utilities.cs
index 2860e9a6be..1b4a243543 100644
--- a/DisCatSharp/Utilities.cs
+++ b/DisCatSharp/Utilities.cs
@@ -103,7 +103,7 @@ static Utilities()
return str;
str = Regex.Replace(str, @"([a-zA-Z0-9]{68,})", "{WEBHOOK_OR_INTERACTION_TOKEN}"); // Any alphanumeric string this long is likely to be sensitive information anyways
- str = Regex.Replace(str, @"(mfa\.[a-z0-9_-]{20,})|((?[a-z0-9_-]{23,28})\.(?[a-z0-9_-]{6,7})\.(?[a-z0-9_-]{27,}))", "{ACCOUNT_TOKEN}");
+ str = Regex.Replace(str, @"(mfa\.[a-z0-9_-]{20,})|((?[a-z0-9_-]{23,28})\.(?[a-z0-9_-]{6,7})\.(?[a-z0-9_-]{27,}))", "{BOT_OR_USER_TOKEN}");
return str;
}
From 9cb90eea2bab87ca922b9555616803f8b629bf27 Mon Sep 17 00:00:00 2001
From: Lala Sabathil
Date: Fri, 24 May 2024 09:48:24 +0200
Subject: [PATCH 7/8] chore: fix docs
---
DisCatSharp/DiscordConfiguration.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/DisCatSharp/DiscordConfiguration.cs b/DisCatSharp/DiscordConfiguration.cs
index 891128dd03..60d96f3551 100644
--- a/DisCatSharp/DiscordConfiguration.cs
+++ b/DisCatSharp/DiscordConfiguration.cs
@@ -239,10 +239,12 @@ public UdpClientFactoryDelegate UdpClientFactory
///
public IServiceProvider ServiceProvider { internal get; init; } = new ServiceCollection().BuildServiceProvider(true);
+ // TODO: Add disclaimer and docs for sentry
///
- /// Whether to report missing fields for discord object.
+ /// Whether to emable sentry.
/// This helps us to track missing data and library bugs better.
/// Defaults to .
+ /// TODO: Add disclaimer and docs.
///
public bool EnableSentry { internal get; set; } = false;
From 50ccaa229f2d93dc7d523de16ae7f7d61167df49 Mon Sep 17 00:00:00 2001
From: Lala Sabathil
Date: Fri, 24 May 2024 09:49:00 +0200
Subject: [PATCH 8/8] revert: ex can be in senex since it's not read by sentry
itself, rather if u manually call it
might need more fixes
---
DisCatSharp/Net/Rest/RestClient.cs | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/DisCatSharp/Net/Rest/RestClient.cs b/DisCatSharp/Net/Rest/RestClient.cs
index 40bd26eb2b..1060194935 100644
--- a/DisCatSharp/Net/Rest/RestClient.cs
+++ b/DisCatSharp/Net/Rest/RestClient.cs
@@ -563,8 +563,7 @@ private async Task ExecuteRequestAsync(BaseRestRequest request, RateLimitBucket?
case HttpStatusCode.BadRequest:
case HttpStatusCode.MethodNotAllowed:
ex = new BadRequestException(request, response);
- // ex won't be added to avoid possible leaks
- senex = new(ex.Message + "\nJson Response: " + ((ex as BadRequestException)?.JsonMessage ?? "null"));
+ senex = new(ex.Message + "\nJson Response: " + ((ex as BadRequestException)?.JsonMessage ?? "null"), ex);
break;
case HttpStatusCode.Unauthorized:
@@ -629,8 +628,7 @@ private async Task ExecuteRequestAsync(BaseRestRequest request, RateLimitBucket?
case HttpStatusCode.ServiceUnavailable:
case HttpStatusCode.GatewayTimeout:
ex = new ServerErrorException(request, response);
- // ex won't be added to avoid possible leaks
- senex = new(ex.Message + "\nJson Response: " + ((ex as ServerErrorException)!.JsonMessage ?? "null"));
+ senex = new(ex.Message + "\nJson Response: " + ((ex as ServerErrorException)!.JsonMessage ?? "null"), ex);
break;
}