Post a reply

Options
Add an Attachment

If you do not want to add an Attachment to your Post, please leave the Fields blank.

(maximum 10 MB; please compress large files; only common media, archive, text and programming file formats are allowed)

Options

Topic review

martin

WinSCP SessionOptions works in this respect the same way as native .NET NetworkCredential (it also has Password and SecurePassword properties).

See also https://stackoverflow.com/q/32740040/850848
buckethead

martin wrote:

The issue is that just by returning SessionOptions the password is in plain view. Should you wish to make use of the information within SessionOptions for things such auditing, logfiles or pass the object to another process you have to be careful how to handle the object so not to expose the password value by other means. It's all about reducing the risk.

I'm still not sure I understand.
So what do you propose?


ok, if you logged into a website and the password field displayed the characters rather than masking them with say '****' I think this would be considered a risk. What if I wrote a script with the password written as plain text such as $password = 'Pa$$w0rd', is this considered good practice? Nope.

Why does SessionOptions expose the password as plain text? It's even worse when the SecureString was used instead and it immediately decrypts it and presents it back to you.
It should be redacted; the same as it does in the session output property where it shows you the connection string:
winscp> open "sftp://myuser:***@10.1.0.1" -hostkey ssh1234

As mentioned earlier I'm redacting the value myself as soon as a connection is made:
$sessionOptions.Password = "***"
martin

The issue is that just by returning SessionOptions the password is in plain view. Should you wish to make use of the information within SessionOptions for things such auditing, logfiles or pass the object to another process you have to be careful how to handle the object so not to expose the password value by other means. It's all about reducing the risk.

I'm still not sure I understand.
So what do you propose?
Guest

martin wrote:

buckethead wrote:

I'm a little concerned about this too. I've been looking into different parameters to make use of and also found that the password is being exposed. It seems a little pointless having a securePassword option and then making the password available to view in SessionOptions.

I'm not sure I understand. Do you mean that you can read the password from SessionOptions.Password? It that option was not available, what would prevent an attacker from reading the password from SessionOptions.SecurePassword?


It's not about access to the value SessionOptions.SecurePassword as such as you could argue the use of System.Security.SecureString values within any PowerShell script.
The issue is that just by returning SessionOptions the password is in plain view. Should you wish to make use of the information within SessionOptions for things such auditing, logfiles or pass the object to another process you have to be careful how to handle the object so not to expose the password value by other means. It's all about reducing the risk.
martin

buckethead wrote:

I'm a little concerned about this too. I've been looking into different parameters to make use of and also found that the password is being exposed. It seems a little pointless having a securePassword option and then making the password available to view in SessionOptions.

I'm not sure I understand. Do you mean that you can read the password from SessionOptions.Password? It that option was not available, what would prevent an attacker from reading the password from SessionOptions.SecurePassword?
buckethead

Piercenz wrote:

...if I debug the script after the SessionOptions object has been initialized with the SecurePassword, I can see the decoded password as plain text in the Password property of the SessionOptions?
...


I'm a little concerned about this too. I've been looking into different parameters to make use of and also found that the password is being exposed. It seems a little pointless having a securePassword option and then making the password available to view in SessionOptions.
As a workaround I'm redacting the plain text value as soon as a session is open.
martin

Piercenz wrote:

I'm a little bit confused by this approach... Yes the password is not stored in the script as plain text, but if I debug the script after the SessionOptions object has been initialized with the SecurePassword, I can see the decoded password as plain text in the Password property of the SessionOptions?

So essentially anyone can pickup my script, run it in debug mode and see the decrypted password?

I feel like I'm missing something here...

The password is encrypted using your Windows credentials. So if someone picks up the script, he/she won't be able to decode the password, unless that person knows your Windows credentials (or has an access to your Windows session).
Piercenz

I'm a little bit confused by this approach... Yes the password is not stored in the script as plain text, but if I debug the script after the SessionOptions object has been initialized with the SecurePassword, I can see the decoded password as plain text in the Password property of the SessionOptions?

So essentially anyone can pickup my script, run it in debug mode and see the decrypted password?

I feel like I'm missing something here...
martin

Thanks for sharing your solution.
Honky

found it:

1. Generate Hash in Powershell:

Read-Host 'Enter password' -AsSecureString |
ConvertFrom-SecureString |
Out-File 'C:\password.txt'

2. Copy/Paste Hash from password.txt

3. Replace
$sessionOptions.Password = "BLBALBLBA"
with
$sessionOptions.SecurePassword = ConvertTo-SecureString "01000000d08c9ddf0115d1118c7a00c04fc297eb01000000d5e66e657ce0264d9cdffd82e583fec00000000002000000000003660000c00000001000000005351f863d78e0364289ed60022d65a30000000004800000a000000010000000467b753a60f8a4ef0b612880c92ec6c730000000b87f47ffd9c5bafbc1a2a3d39e520199e8b10cb571aa97cd9ec2c43b86fed4fb0c1e40d3b5fc81ecc04dd79f1f71f942140000001c829482c76164fa43e7af395ff2ca3db611821b"
Honky

Secured Password in Powershell Script

Hello WinSCP Guru's,

is there any possibility to use an encrypted password (like in the GUI)in the my Powershell-Script?

param (

    $localPath = "F:\Test-Sync01\",
    $remotePath = "/Test-Sync01/"
)
 
try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "F:\syncapp\WinSCPnet.dll"
 
   

    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions
   
 
    $sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
    $sessionOptions.HostName = "server08"
    $sessionOptions.UserName = "syncusr"
    $sessionOptions.Password  = "BLBALBLA"
    $sessionOptions.SshHostKeyFingerprint = "ssh-rsa 1024 13:d3:ef:ee:4d:cc:22:31:04:aa:1e:cd:7b:c7:42:02"
    $session = New-Object WinSCP.Session

       
 
    try
    {
        # Connect
        $session.Open($sessionOptions)

       
        # Synchronize files to local directory, collect results
        $synchronizationResult = $session.SynchronizeDirectories(
            [WinSCP.SynchronizationMode]::Remote, $localPath, $remotePath, $False)
 
         
        # Iterate over every download
        foreach ($download in $synchronizationResult.Uploads)
        {
            echo $download.FileName
            # Success or error?
            if ($download.Error -eq $Null)
            {
                Write-Host ("Download of {0} succeeded, removing from source" -f
                    $download.FileName)
             
                try
                {
                    Remove-Item $session.EscapeFileMask($download.FileName)
                    Write-Host ("Removing of file {0} succeeded" -f
                        $download.FileName)
                }
                catch [Exception]
                {
                    Write-Host ("Rmoving of file {0} failed" -f
                        $download.FileName)
                }
            }
            else
            {
                Write-Host ("Download of {0} failed: {1}" -f
                    $download.FileName, $download.Error.Message)
            }
        }
    }
    finally
    {
   
        # Disconnect, clean up
        $session.Dispose()
    }
 
    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}


Thanks in advance!