secure string as a varible to a string filed

I have a custom function not written by us and we are using this process to create a semi secure password string:

$pass = Get-Content "C:\Script\UserFolderCreation\file.txt" | ConvertTo-SecureString

Then when I run the function I pass -UserName “Admin” -Password $pass

This does not work but does when I actually put the password in instead of $pass.

The function code I’m running is:

API/REST/PowerShell/Folders/Enhanced-Personal-Folders at master · thycotic/API · GitHub

Is there anyway to modify the parameter for -password to accept the $pass secure string?

Pertinent parts of the code:

<# 

.PARAMETER UseTokenAuthentication This switch parameter is used for username and password authentication to Secret Server in order to generate a token. That token will be used in subsequent API calls. This is a less secure approach, but usefull for a quick test  

.PARAMETER Password Only used if UseTokenAuthentication is called

 #>

[parameter(Mandatory=$true,ParameterSetName="Password",Position=6)]
[parameter(ParameterSetName="TokenAuthentication")]
[String]
$Password

Whether it’s in the function or outside of the function, you are passing a ‘clear text’ password in the API headers normally. I’ve written many API wrappers and it’s not best practice to ask for a string (Visual Studio Code will even tell you that’s bad). If you make the function accept a Credential object in place of Username\Password, you would be passing $Credential.GetNetworkCredential().password in the header or worse the URL. Basically, it can always be reverse engineered if someone know what they are doing, but storing it as a secure string minimally ensure it’s not plain text. Here is an example of working with the credential object:

https://devblogs.microsoft.com/scripting/decrypt-powershell-secure-string-password/

Rob, I understand it can be decrypted as I have done it myself in order to make sure it was passing the correct password when I found this was failing. I’m not debating that this is super secure just trying to be a little more secure than putting the password in the script in plain text.

My feelings is a change to the code in the function for the type of data it is expecting would resolve this but I’m not sure and why I’m looking for additional help.

Agree with Rob. This is not a good idea. With that being said, you can change the parameter type to [securestring], but the body of the function would also need to update to handle [securestring] instead of [string]. The simple way to do that is just convert it back in the body. To do that you can use the [system.net.networkcredential] class.

Param    (
    [securestring]
    $Password    
)

    [string]$password = [System.Net.NetworkCredential]::new("", $password).Password


    "Your password is $password"

 

Everyone I agree this is not a great idea but it is better than putting the password in a script in clear text isn’t it? I need to use this script to automate a task and I’m trying to find the best way to complete this. I understand it is security by obscurity but isn’t it better than nothing.

How I get the secure file:

Read-Host -Prompt "Enter password" -AsSecureString | ConvertFrom-SecureString | Out-File "C:\Script\UserFolderCreation\file.txt"

My understanding is that this creation of a string is locked to the machine and the user account that created the string. If I try to use or decrypt the file with a different account I get:
ConvertTo-SecureString : Key not valid for use in specified state.

Since this is not a domain or local pc account I’m using, I really do not know of a better way to do this for automation. I’m open to ideas around the discussion though.

You are correct about how the string is secured with a key only the user account has access to and given your environment this is probably the best way to do it. And this will prevent anyone else being able to convert it back to plain text. The only issue is when that user runs the code, the plain text password is still stored in memory. There are many exploits such as Mimikatz, that reads plain text passwords stored in memory. In a perfect world, either Windows Authentication or Certificates would be used for authentication.

Here’s Microsoft’s official take on it.

https://docs.microsoft.com/en-us/dotnet/api/system.security.securestring?view=net-5.0

https://github.com/dotnet/platform-compat/blob/master/docs/DE0001.md

Thank you everyone for your support and responses regarding this issue!