Skip to content

Commit bf20c20

Browse files
authored
Merge pull request #13 from mjcheetham/fix-tracesecrets
Fix secret tracing to print correct masking characters
2 parents 882b9f0 + f6d0187 commit bf20c20

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

src/Microsoft.Git.CredentialManager/Trace.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ void WriteLineSecrets(
9494
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "");
9595
}
9696

97-
internal class Trace : ITrace, IDisposable
97+
public class Trace : ITrace, IDisposable
9898
{
9999
private readonly object _writersLock = new object();
100100
private readonly List<TextWriter> _writers = new List<TextWriter>();
@@ -211,7 +211,7 @@ public void WriteLineSecrets(
211211
{
212212
string message = this.EnableSecretTracing
213213
? string.Format(format, secrets)
214-
: string.Format(format, secrets.Select(x => "********"));
214+
: string.Format(format, secrets.Select(_ => (object)"********").ToArray());
215215

216216
WriteLine(message, filePath, lineNumber, memberName);
217217
}

src/git-credential-manager/Application.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ public static async Task<int> RunAsync(string[] args)
6161
if (context.IsEnvironmentVariableTruthy(Constants.EnvironmentVariables.GcmTraceSecrets, false))
6262
{
6363
context.Trace.EnableSecretTracing = true;
64-
context.StdError.WriteLine("Secret tracing is enabled. Trace output may contain sensitive information.");
64+
context.StdError.WriteLine(
65+
"warning: Secret tracing is enabled. Trace output may contain sensitive information.");
6566
}
6667

6768
// Register all supported host providers
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
using System;
5+
using System.IO;
6+
using System.Text;
7+
using Xunit;
8+
9+
namespace Microsoft.Git.CredentialManager.Tests
10+
{
11+
public class TraceTests
12+
{
13+
[Fact]
14+
public void Trace_WriteLineSecrets_SecretTracingEnabled_WritesSecretValues()
15+
{
16+
const string secret1 = "foo";
17+
const string secret2 = "bar";
18+
const string secret3 = "test";
19+
20+
var sb = new StringBuilder();
21+
var listener = new StringWriter(sb);
22+
23+
var trace = new Trace();
24+
trace.AddListener(listener);
25+
trace.EnableSecretTracing = true;
26+
27+
trace.WriteLineSecrets("Secrets: {0} {1} {2}", new object[]{ secret1, secret2, secret3 });
28+
29+
string expectedTraceEnd = $"Secrets: {secret1} {secret2} {secret3}\n";
30+
string actualTrace = sb.ToString();
31+
32+
Assert.EndsWith(expectedTraceEnd, actualTrace, StringComparison.Ordinal);
33+
}
34+
35+
[Fact]
36+
public void Trace_WriteLineSecrets_SecretTracingDisabled_WritesMaskedValues()
37+
{
38+
const string mask = "********";
39+
const string secret1 = "foo";
40+
const string secret2 = "bar";
41+
const string secret3 = "test";
42+
43+
var sb = new StringBuilder();
44+
var listener = new StringWriter(sb);
45+
46+
var trace = new Trace();
47+
trace.AddListener(listener);
48+
trace.EnableSecretTracing = false;
49+
50+
trace.WriteLineSecrets("Secrets: {0} {1} {2}", new object[]{ secret1, secret2, secret3 });
51+
52+
string expectedTraceEnd = $"Secrets: {mask} {mask} {mask}\n";
53+
string actualTrace = sb.ToString();
54+
55+
Assert.EndsWith(expectedTraceEnd, actualTrace, StringComparison.Ordinal);
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)