Please lay your expert opinion on the security of these two scripts:
[Note: The output of these two scripts will be pipelined. They will not be assigned to any variable."]
First :
Function GetFrom-SecureString([SecureString]$SecureString) {
[IntPtr]$valuePtr = [IntPtr]::Zero
try {
$valuePtr = [Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($SecureString)
return [Runtime.InteropServices.Marshal]::PtrToStringUni($valuePtr);
}
finally {
[Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($valuePtr);
}
}
Second :
Function Decode-SecureString([SecureString]$SecureString){
try{
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureString)
$length = [Runtime.InteropServices.Marshal]::ReadInt32($bstr, -4)
for ( $i = 0; $i -lt $length; ++$i ) {
[CHAR][Runtime.InteropServices.Marshal]::ReadByte($bstr, $i)
}
}
finally{
if ( $bstr -ne [IntPtr]::Zero ) {
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
}
}
}
I know that its not secure to use $cred.GetNetworkCredential().Password because it converts the securestring to the memory first, and many have pointed out to me to use marshalling. So, I have constructed the above two scripts as trial and I would like to know if there's anything reckless maneuver in these two scripts.
Edit:
I have updated my second string to clean up the BSTR by implementing :
finally{
if ( $bstr -ne [IntPtr]::Zero ) {
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr) #Frees the BSTR.
}
}
However, the returned values captured in the pipeline seem to be not at all secure since it is in the memory too until its cleaned up.
[Note: I haven't yet programmed the script which will accept the pipelined values.]
The very point of using a securestring seems to be destroyed by decrypting it back to plaintext. As if we should never decrypt the securestring. Correct me if I am wrong.
stringobject. How you suggest to remove it from memory? - user4003407SecureStringis that you can't forcibly overwrite the plain-textStringcopy in memory after you do so (it's a managedStringobject). That's a limitation you're going to have to live with, if you really do need to decrypt aSecureStringto plain-text. - Bill_Stewart