The first step working with automation and PowerShell is completing an authentication process against a remote server and providing the right credentials. In the previous article our aim was to raise the awareness of how SecureString can be used in a very unsafe way, now we simply would like to show you what to avoid and how to store your credentials.
Three things to avoid:
- [always] clear text passwords It’s obvious. Think that you source code and software development is always evolving and maybe one day your local repository of code will be managed differently thru a proper development pipeline. The first steps towards should be implementing source-code management, quality assurance, testing or simply published to GitHub and your precious secrets too. Malicious software can harvest hard-drives and file shares looking for credentials. Other users with less privileges can maybe execute the script and read the file and access to your secrets. So on and so forth..
- [if possible] security thru obscurity
What seems a good idea is making clear text password or strings not human readable or just more obscure is most of the time counter-productive. If you think about it this is also popular technique used by attackers with powershell or javascript exploits.
In short: obscurity is not a recipe for security and can generate false positive results when looking for malicious code and just delay of few minutes an attacker.
Please have a look at this example:1234567891011121314#Convert my password ("ThisIsMySecret!") in a Obfuscated SecureString$password = "ThisIsMySecret!" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString<#This will be the result of Write-Output $password01000000d08c9ddf0115d1118c7a00c04fc297eb010000001e602632b1e561408dbde95ace3db534000000000200000000001066000000010000200000005476b16aba077b5262a7b0bc2410bd5210b3962e9a3a926d12c71c512c668b86000000000e8000000002000020000000c7dd30b3fd21100d1427861e081440f1964509a4cfd40aee0c5fa7b15e8c2ea8200000004e055d51c394c3b82689cf89c2f5a00a884b99f28c1850bd045c9102bf20ea7440000000dfa9d6360a10a88eca6123a2fb45fc11f7952cf5ab7715286aca18d42890e7a594a961346f7587122143fe881b16c67ef74f6551f0160bf1c922a50bbc7d1751#>#If I want to decode it back under the same user session using the function defined in the previous blog post and share on github :dssp -password $($password | ConvertTo-SecureString)ThisIsMySecret! # Tadaaa! - [if possible] store passwords in the registry
More secure than store the credential in clear text in your source code, but the registry is always accessible by any users and application and the references in your source code to the registry key (HKCU, HKLM) are easy to find out.
How to store your credentials
The Export-Clixml cmdlet encrypts credential objects by using the Windows Data Protection API . This ensures that only your user account can de-crypt the contents of the credential object.
1 2 3 4 5 6 7 8 |
#Export to XML your credential Get-Credential | Export-Clixml mycred.xml #Import from XML your credential PS C:\Users\Paolo> Import-Clixml .\mycred.xml UserName Password -------- -------- user System.Security.SecureString |
Is this method bulletproof? No, within the same user session can be considered a trivial exercise to decode the credential.
How to manage credential under different user session/context
Can became a quickly convoluted, but I suggest you to use a KEY (a new password) to encrypt your secret :
1 |
ConvertFrom-SecureString -SecureString $password -Key $key |
Now your key is another password to store in a secure place.
Conclusions
Protect credential is a very delicate task and most of the time very difficult to achieve. Whenever possible prefer an interactive method. Clear your cached credential from your session as soon is not required any more.