Redacting Sensitive Information with PowerShell
Monday, 12 August 2013
You might sometimes run into a situation where you've got a serialized object stream, and want to redact sensitive information out of that stream. For example, consider the following object:
001
002 003 004 005 006 007 008 009 |
$objectToSerialize = [PSCustomObject] @{
Name = "Lee" SocialSecurityNumber = "SomeSecretNumber" Address = "1234 Something Road" GateCode = [PSCustomObject] @{ Prefix = 1234 Password = "SomeSecretPassword" } } |
In this, you want to remove any property value that says "SomeSecret".
PowerShell makes this fairly easy, since the PSObject special property on every type gives you access to an object's methods and properties. For each property value, you can check if it contains sensitive information - and if so, redact it.
Some properties are not simple properties, though. They might be objects with multiple writable properties themselves. In that case, you need to go down the worm hole even further.
Here's a script that demonstrates one approach: Remove-PrivateInformation.ps1
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 |
param($objectToSerialize)
function CleanObject param($objectToClean) foreach($property in $objectToClean.PSObject.Properties) { ## See if there are any settable properties of this property $settableProperties = $property.Value.PSObject.Properties | ? { $_.IsSettable } if(@($settableProperties).Count -gt 0) { CleanObject $property.Value } ## Otherwise, we can clean it if($property.IsSettable -and ($property.Value -match "SomeSecret")) { $property.Value = "Redacted!" } } } ## Assuming you can't change $objectToSerialize directly. Otherwise, apply CleanObject ## to the object directly. $serialized = [System.Management.Automation.PSSerializer]::Serialize($objectToSerialize) $objectToClean = [System.Management.Automation .PSSerializer]::Deserialize($serialized) CleanObject $objectToClean$objectToClean |
And the result:
11 [C:\windows\system32] >> $objectToSerialize = [PSCustomObject] @{ >> Name = "Lee" >> SocialSecurityNumber = "SomeSecretNumber" >> Address = "1234 Something Road" >> GateCode = [PSCustomObject] @{ >> Prefix = 1234 >> Password = "SomeSecretPassword" >> } >> } >> 12 [C:\windows\system32] >> Remove-PrivateInformation.ps1 $objectToSerialize | Format-List Name : Lee SocialSecurityNumber : Redacted! Address : 1234 Something Road GateCode : @{Prefix=1234; Password=Redacted!} 13 [C:\windows\system32]