Initial commit: BizTalk SAP environment inventory
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace BizTalkSapEnvironmentInventory.Infrastructure
|
||||
{
|
||||
/// <summary>
|
||||
/// Zentraler Schutz gegen die Aufnahme von Kennwörtern, Tokens und Schlüsseldaten in Log oder DOCX.
|
||||
/// </summary>
|
||||
internal static class SensitiveDataSanitizer
|
||||
{
|
||||
private static readonly string[] SensitiveFragments =
|
||||
{
|
||||
"password", "passwd", "passphrase", "pwd", "secret", "token",
|
||||
"privatekey", "clientsecret", "accesskey", "apikey", "connectionstring"
|
||||
};
|
||||
|
||||
private static readonly Regex UriSecretPattern = new Regex(
|
||||
@"(?i)(password|passwd|passphrase|pwd|secret|token|clientsecret)\s*=\s*(?:""[^""]*""|'[^']*'|[^;&\s""']+)",
|
||||
RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
||||
|
||||
private static readonly Regex UserInfoPattern = new Regex(
|
||||
@"(?i)([a-z][a-z0-9+.-]*://)([^/@:\s]+):([^/@\s]+)@",
|
||||
RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
||||
|
||||
/// <summary>
|
||||
/// Erkennt sensitive Feldnamen unabhängig von Großschreibung und Trennzeichen.
|
||||
/// </summary>
|
||||
public static bool IsSensitiveName(string name)
|
||||
{
|
||||
var normalized = (name ?? string.Empty).Replace("_", string.Empty)
|
||||
.Replace("-", string.Empty);
|
||||
return SensitiveFragments.Any(fragment =>
|
||||
normalized.IndexOf(fragment, StringComparison.OrdinalIgnoreCase) >= 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redigiert einen Wert anhand seines semantischen Feldnamens.
|
||||
/// </summary>
|
||||
public static string RedactValue(string name, string value)
|
||||
{
|
||||
if (IsSensitiveName(name))
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(value)
|
||||
? "Nicht gesetzt"
|
||||
: "Konfiguriert (Wert nicht dokumentiert)";
|
||||
}
|
||||
|
||||
return SanitizeText(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entfernt Secrets aus URI-/Key-Value-Texten und eingebetteten Benutzerinformationen.
|
||||
/// </summary>
|
||||
public static string SanitizeText(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var sanitized = UriSecretPattern.Replace(
|
||||
value,
|
||||
match => match.Groups[1].Value + "=***REDACTED***");
|
||||
sanitized = UserInfoPattern.Replace(
|
||||
sanitized,
|
||||
match => match.Groups[1].Value + match.Groups[2].Value + ":***REDACTED***@");
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Erstellt eine secret-bereinigte Kopie eines XML-Teilbaums.
|
||||
/// </summary>
|
||||
public static XElement SanitizeXml(XElement source)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (IsSensitiveName(source.Name.LocalName)
|
||||
|| IsCipherElement(source.Name.LocalName))
|
||||
{
|
||||
return new XElement(source.Name, "***REDACTED***");
|
||||
}
|
||||
|
||||
var result = new XElement(source.Name);
|
||||
foreach (var attribute in source.Attributes())
|
||||
{
|
||||
result.Add(new XAttribute(
|
||||
attribute.Name,
|
||||
IsSensitiveName(attribute.Name.LocalName)
|
||||
? "***REDACTED***"
|
||||
: SanitizeText(attribute.Value)));
|
||||
}
|
||||
|
||||
foreach (var node in source.Nodes())
|
||||
{
|
||||
var element = node as XElement;
|
||||
if (element != null)
|
||||
{
|
||||
result.Add(SanitizeXml(element));
|
||||
continue;
|
||||
}
|
||||
|
||||
var text = node as XText;
|
||||
if (text != null)
|
||||
{
|
||||
result.Add(new XText(SanitizeText(text.Value)));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool IsCipherElement(string name)
|
||||
{
|
||||
return string.Equals(name, "EncryptedData", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(name, "CipherData", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(name, "CipherValue", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user