-
Notifications
You must be signed in to change notification settings - Fork 645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix issue 1043: Obfuscate AI data on request redirect #5236
Changes from 2 commits
2a885cb
53311e8
85b1b48
b0c018b
81bb4e2
7b1d98c
62e8928
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,11 +2,37 @@ | |
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace NuGetGallery | ||
{ | ||
internal struct ObfuscateMetadata | ||
{ | ||
/// <summary> | ||
/// A <see cref="System.Text.RegularExpressions.Regex" to be used for matching the value to be obfuscated./> | ||
/// </summary> | ||
public string ObfuscateTemplate | ||
{ | ||
get; | ||
} | ||
|
||
/// <summary> | ||
/// The obfuscation value. | ||
/// </summary> | ||
public string ObfuscateValue | ||
{ | ||
get; | ||
} | ||
|
||
public ObfuscateMetadata(string obfuscateTemplate, string obfuscateValue) | ||
{ | ||
ObfuscateTemplate = obfuscateTemplate; | ||
ObfuscateValue = obfuscateValue; | ||
} | ||
} | ||
|
||
internal static class Obfuscator | ||
{ | ||
/// <summary> | ||
|
@@ -25,9 +51,55 @@ internal static class Obfuscator | |
"Users/Profiles", | ||
"Users/ResetPassword"}; | ||
|
||
internal static readonly Dictionary<string, ObfuscateMetadata> ObfuscatedTemplates = new Dictionary<string, ObfuscateMetadata> | ||
{ | ||
{@"/packages/(.+)/owners/(.+)/confirm/(.+)", new ObfuscateMetadata(@"/owners/(.+)/confirm", $"/owners/{DefaultTelemetryUserName}/confirm")}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should probably compile these regular expressions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we already use compiled regex expressions in the gallery? .NET only caches up to 15 compiled regex expressions by default (source here), and compiling a regex is rather expensive. TLDR: Compiling regex may result in worse performance, we should do some due diligence before enabling it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice read, good point. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did simple perf tests with: static regex and compiled instance regex . The results show similar perf characteristics. |
||
{@"/packages/(.+)/owners/(.+)/reject/(.+)", new ObfuscateMetadata(@"/owners/(.+)/reject", $"/owners/{DefaultTelemetryUserName}/reject") }, | ||
{@"/packages/(.+)/owners/(.+)/cancel/(.+)", new ObfuscateMetadata(@"/owners/(.+)/cancel", $"/owners/{DefaultTelemetryUserName}/cancel") }, | ||
{@"/account/confirm/(.+)/(.+)", new ObfuscateMetadata(@"/account/confirm/(.+)/", $"/account/confirm/{DefaultTelemetryUserName}/") }, | ||
{@"/account/delete/(.+)", new ObfuscateMetadata(@"/account/delete/(.+)", $"/account/delete/{DefaultTelemetryUserName}") }, | ||
{@"/profiles/(.+)", new ObfuscateMetadata(@"/profiles/(.+)", $"/profiles/{DefaultTelemetryUserName}") }, | ||
{@"/account/setpassword/(.+)/(.+)", new ObfuscateMetadata(@"/setpassword/(.+)/", $"/setpassword/{DefaultTelemetryUserName}/") }, | ||
{@"/account/forgotpassword/(.+)/(.+)", new ObfuscateMetadata(@"/forgotpassword/(.+)/", $"/forgotpassword/{DefaultTelemetryUserName}/") } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tend to use verbatim string when working with regex expressions. For these regex there is no difference. |
||
}; | ||
|
||
internal static string DefaultObfuscatedUrl(Uri url) | ||
{ | ||
return url == null ? string.Empty : $"{url.Scheme}://{url.Host}/{DefaultTelemetryUserName}"; | ||
} | ||
|
||
internal static Uri ObfuscateUrl(Uri url) | ||
{ | ||
if (url == null) | ||
{ | ||
return url; | ||
} | ||
return new Uri($"{url.Scheme}://{url.Host}{Obfuscate(url.AbsolutePath)}"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we lose port? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (e.g. if a customer is running gallery on a non-standard port) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added the port. |
||
} | ||
|
||
internal static string Obfuscate(string value) | ||
{ | ||
string obfuscatedTemplateKey = null; | ||
if (value == null || !NeedsObfuscation(value, out obfuscatedTemplateKey)) | ||
{ | ||
return value; | ||
} | ||
string obfuscatedValue = Regex.Replace(value, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this case sensitive? I think our URLs are: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added case insensitive option. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add timeouts to all regex matches: #4038 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added the timeouts. |
||
ObfuscatedTemplates[obfuscatedTemplateKey].ObfuscateTemplate, | ||
ObfuscatedTemplates[obfuscatedTemplateKey].ObfuscateValue); | ||
return obfuscatedValue; | ||
} | ||
|
||
internal static bool NeedsObfuscation(string valueToBeVerified, out string obfuscatedTemplateKey) | ||
{ | ||
obfuscatedTemplateKey = string.Empty; | ||
var match = ObfuscatedTemplates.Where(template => Regex.IsMatch(valueToBeVerified.ToLower(), template.Key)).FirstOrDefault(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use case insensitive regex instead of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated to use case insensitive. |
||
if (match.Key == null) | ||
{ | ||
return false; | ||
} | ||
obfuscatedTemplateKey = match.Key; | ||
return true; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DefaultObfuscatedUrl was also called by QuietLog.GetObfuscatedServerVariables. Can this use the same technique?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be updated if needed in a different change.