Skip to content

Commit 3b2b683

Browse files
[In-proc] Worker termination path sanitizing (#10397)
1 parent 2f9acbd commit 3b2b683

File tree

4 files changed

+30
-2
lines changed

4 files changed

+30
-2
lines changed

release_notes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@
3333
- Update PowerShell 7.4 worker to [4.0.4021](https://github.com/Azure/azure-functions-powershell-worker/releases/tag/v4.0.4021)
3434
- Trim FunctionsNetHost artifacts (#10364)
3535
- Resolved thread safety issue in the `GrpcWorkerChannel.LoadResponse` method. (#10352)
36+
- Worker termination path updated with sanitized logging (#10397)

src/WebJobs.Script/Sanitizer.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Text.RegularExpressions;
56
using Newtonsoft.Json.Linq;
67

78
namespace Microsoft.Azure.WebJobs.Logging
@@ -20,6 +21,21 @@ internal static class Sanitizer
2021
internal static readonly string[] CredentialTokens = new string[] { "Token=", "DefaultEndpointsProtocol=http", "AccountKey=", "Data Source=", "Server=", "Password=", "pwd=", "&sig=", "&sig=", "?sig=", "SharedAccessKey=" };
2122
private static readonly string[] CredentialNameFragments = new[] { "password", "pwd", "key", "secret", "token", "sas" };
2223

24+
// Pattern of format : "<protocol>://<username>:<password>@<address>:<port>"
25+
private static readonly string Pattern = @"
26+
\b([a-zA-Z]+) # Capture protocol
27+
:\/\/ # '://'
28+
([^:/\s]+) # Capture username
29+
: # ':'
30+
([^@/\s]+) # Capture password
31+
@ # '@'
32+
([^:/\s]+) # Capture address
33+
: # ':'
34+
([0-9]+)\b # Capture port number
35+
";
36+
37+
private static readonly Regex Regex = new Regex(Pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
38+
2339
/// <summary>
2440
/// Removes well-known credential strings from strings.
2541
/// </summary>
@@ -73,6 +89,12 @@ internal static string Sanitize(string input)
7389
}
7490
}
7591

92+
// This check avoids unnecessary regex evaluation if the input does not contain any url
93+
if (input.Contains(":"))
94+
{
95+
t = Regex.Replace(t, SecretReplacement);
96+
}
97+
7698
return t;
7799
}
78100

@@ -153,6 +175,6 @@ static JToken Sanitize(JToken token)
153175
/// Checks if a string even *possibly* contains one of our <see cref="CredentialTokens"/>.
154176
/// Useful for short-circuiting more expensive checks and replacements if it's known we wouldn't do anything.
155177
/// </summary>
156-
internal static bool MayContainCredentials(string input) => input.Contains("=");
178+
internal static bool MayContainCredentials(string input) => input.Contains("=") || input.Contains(":");
157179
}
158180
}

src/WebJobs.Script/Workers/ProcessManagement/WorkerProcess.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ private void OnProcessExited(object sender, EventArgs e)
173173
else
174174
{
175175
string exceptionMessage = string.Join(",", _processStdErrDataQueue.Where(s => !string.IsNullOrEmpty(s)));
176-
var processExitEx = new WorkerProcessExitException($"{Process.StartInfo.FileName} exited with code {Process.ExitCode} (0x{Process.ExitCode.ToString("X")})", new Exception(exceptionMessage));
176+
string sanitizedExceptionMessage = Sanitizer.Sanitize(exceptionMessage);
177+
var processExitEx = new WorkerProcessExitException($"{Process.StartInfo.FileName} exited with code {Process.ExitCode} (0x{Process.ExitCode.ToString("X")})", new Exception(sanitizedExceptionMessage));
177178
processExitEx.ExitCode = Process.ExitCode;
178179
processExitEx.Pid = Process.Id;
179180
HandleWorkerProcessExitError(processExitEx);

test/WebJobs.Script.Tests/SanitizerTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ public class SanitizerTests
3434
[InlineData("SharedAccessKey=foo", "[Hidden Credential]")]
3535
[InlineData(@"Hey=AS1$@%#$%W-k2j"";SharedAccessKey=foo,Data Source=barzons,Server=bathouse'testing", @"Hey=AS1$@%#$%W-k2j"";[Hidden Credential]'testing")]
3636
[InlineData("test?sig=", "test[Hidden Credential]")]
37+
[InlineData("aaa://aaa:[email protected]:1111", "[Hidden Credential]")]
38+
[InlineData("test,aaa://aaa:[email protected]:1111,test", "test,[Hidden Credential],test")]
39+
[InlineData(@"some text abc://abc:[email protected]:1111 some text abc://abc:[email protected]:1111 text", @"some text [Hidden Credential] some text [Hidden Credential] text")]
40+
[InlineData(@"some text abc://abc:[email protected]:1111 some text AccountKey=heyyyyyyy text", @"some text [Hidden Credential] some text [Hidden Credential]")]
3741
public void SanitizeString(string input, string expectedOutput)
3842
{
3943
var sanitized = Sanitizer.Sanitize(input);

0 commit comments

Comments
 (0)