Skip to content
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

Improve host.json sanitization #9459

Merged
merged 4 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
- Add new Host to Worker RPC extensibility feature for out-of-proc workers. (https://github.com/Azure/azure-functions-host/pull/9292)
- Apply capabilities on environment reload (placeholder mode scenarios) (https://github.com/Azure/azure-functions-host/pull/9367)
- Update PowerShell Worker 7.2 to 4.0.2890 [Release Note](https://github.com/Azure/azure-functions-powershell-worker/releases/tag/v4.0.2890)
- Improve host.json sanitization
57 changes: 55 additions & 2 deletions src/WebJobs.Script/Config/HostJsonFileConfigurationSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public class HostJsonFileConfigurationProvider : ConfigurationProvider
"customHandler", "httpWorker", "extensions", "concurrency"
};

private static readonly string[] CredentialNameFragments = new[] { "password", "pwd", "key", "secret", "token", "sas" };

private readonly HostJsonFileConfigurationSource _configurationSource;
private readonly Stack<string> _path;
private readonly ILogger _logger;
Expand Down Expand Up @@ -275,14 +277,65 @@ private JObject TryAddBundleConfiguration(JObject content, string bundleId, stri

internal static string SanitizeHostJson(JObject hostJsonObject)
{
JObject sanitizedObject = new JObject();
static bool IsPotentialCredential(string name)
{
foreach (string fragment in CredentialNameFragments)
{
if (name.Contains(fragment, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}

return false;
}

static JToken Sanitize(JToken token)
{
if (token is JObject obj)
{
JObject sanitized = new JObject();
foreach (var prop in obj)
{
if (IsPotentialCredential(prop.Key))
{
sanitized[prop.Key] = Sanitizer.SecretReplacement;
}
else
{
sanitized[prop.Key] = Sanitize(prop.Value);
}
}

return sanitized;
}

if (token is JArray arr)
{
JArray sanitized = new JArray();
foreach (var value in arr)
{
sanitized.Add(Sanitize(value));
}

return sanitized;
}

if (token.Type == JTokenType.String)
{
return Sanitizer.Sanitize(token.ToString());
}

return token;
}

JObject sanitizedObject = new JObject();
foreach (var propName in WellKnownHostJsonProperties)
{
var propValue = hostJsonObject[propName];
if (propValue != null)
{
sanitizedObject[propName] = propValue;
sanitizedObject[propName] = Sanitize(propValue);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/WebJobs.Script/Sanitizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Microsoft.Azure.WebJobs.Logging
// Note: This file is shared between the WebJobs SDK and Script repos. Update both if changes are needed.
internal static class Sanitizer
{
private const string SecretReplacement = "[Hidden Credential]";
public const string SecretReplacement = "[Hidden Credential]";
private static readonly char[] ValueTerminators = new char[] { '<', '"', '\'' };

// List of keywords that should not be replaced with [Hidden Credential]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,12 @@ public void Initialize_Sanitizes_HostJsonLog()
'logging': {
'categoryFilter': {
'defaultLevel': 'Information'
}
},
'prop': 'Hey=AS1$@%#$%W-k2j"";SharedAccessKey=foo,Data Source=barzons,Server=bathouse""testing',
'values': [ 'plain', 10, 'Password=hunter2' ],
'my-password': 'hunter2',
'service_token': 'token',
'StorageSas': 'access'
},
'Values': {
'MyCustomValue': 'abc'
Expand All @@ -182,7 +187,12 @@ public void Initialize_Sanitizes_HostJsonLog()
'logging': {
'categoryFilter': {
'defaultLevel': 'Information'
}
},
'prop': 'Hey=AS1$@%#$%W-k2j"";[Hidden Credential]""testing',
'values': [ 'plain', 10, '[Hidden Credential]' ],
'my-password': '[Hidden Credential]',
'service_token': '[Hidden Credential]',
'StorageSas': '[Hidden Credential]'
}
}";

Expand Down