FileZilla WinCred Patch

Direct download links

Content

The problem

FileZilla stores passwords from the site manager in the clear. On Windows, the file C:\Users\username\AppData\Roaming\FileZilla\sitemanager.xml contains passwords in the clear or, in recent versions of FileZilla, in Base-64 encoding.

This is a major security vulnerability since a malware can harvest passwords for remote sites. This is especially a problem for web admins who use FileZilla to access their web sites. If the admin's desktop is compromised, then all his sites are compromised.

It has been argued on some forums that FTP passwords are transmitted in the clear anyway and storing them in the clear is not worse. This is true for FTP. But who is going to use the plain old FTP these days? Careful people use SFTP with FileZilla. And SFTP is encrypted. So, storing passwords in the clear is an actual critical security issue.

Several feature requests were logged in the FileZilla bug tracking system over the years, without response so far, notably tickets #3176 (logged in 2007), #2935 (logged in 2008) and #5530 (logged in 2010).

Although not reported as such, the same problem exists in the file filezilla.xml where FileZilla stores its general options and settings. Among these settings, some are critical like passwords for proxies. In a corporate environment, it is common to use an authenticated proxy using the corporate LDAP username and passwords. In filezilla.xml, these passwords are also stored in plain text, no even in Base-64 like site passwords. This is also a major security issue.

Solutions

Solution 1: Encrypt the disk where the settings are stored

This has been proposed as a workaround in the FileZilla bug tracking system. But this is not a true solution. It pushes the burden to the user. Moreover, once mounted, the encrypted disk is accessible to all other processes on the system.

Solution 2: Modify FileZilla to support a master password

The master password would be used to encrypt all or parts of sitemanager.xml and filezilla.xml. This is the way Firefox protects its remote passwords. See ticket #2935. This is probably the best and most portable solution.

Solution 3: Modify FileZilla to use the operating system security facilities

The operating system primitives would be used to encrypt all or parts of sitemanager.xml and filezilla.xml. See ticket #5530. This is a less portable solution, by definition. But it can be very simple to implement.

The wincred patch

The so-called wincred patch is an implementation of the solution 3 on Microsoft Windows. It is a very simple patch. It uses the users's Windows credentials to encrypt passwords, just like many standard Microsoft tools, through the Win32 function CryptProtectData. The critical secure values, essentially passwords, are encrypted and the encrypted result is saved in the XML file in Base-64 encoding with the XML attribute encoding="wincred".

Pros:

Cons:

XML encoding:

When reading the file sitemanager.xml, all forms of <Pass> tag are recognized. When writing the file, all new passwords are stored with encoding="wincred".

Similarly, when reading the file filezilla.xml, all forms of <Setting> tag are recognized. When writing the file, all passwords are stored with encoding="wincred".

Installing the wincred patch

FileZilla version 3.15.0.2 has been recompiled for Windows with the wincred patch. This patched version is identified as "3.15.0.299" (other namings using "-wincred" were tried but broke the build process).

The corresponding installer is FileZilla-3.15.0.299-wincred-win64-setup.exe

If you do not trust a third-party installer for FileZilla, I will not blame you, being myself paranoid about security. If you do not want to install the prebuilt installer, the next section explains how to rebuild FileZilla from scratch with this patch. The patch file is simple and easy to review for security check.

Recompiling FileZilla on Windows with the wincred patch

This section describes how to recompile FileZilla on Windows 64-bits with the wincred patch. This description is based on the FileZilla wiki with some corrections and additions.

Prepare the build environment

Download the file nsis-2.46.5-Unicode-setup.exe and run it. This installs the NSIS Unicode version. This will be used to build the installer..

Download the file msys2-x86_64-20150512.exe and run it. This installs the MSYS2 environment for Windows 64-bits. By default, the MSYS2 environment is installed in C:\msys64.

To create an MSYS2 command windows, go to the start menu, select "MSYS2 64bits", then "MSYS2 Shell". Open such a shell window and type the following command:

pacman -Syu

Accept all installations. At the end of the procedure, close the MSYS2 shell window. From the Windows Explorer, execute the script C:\msys64\autorebase.bat. Open a new MSYS2 shell window and execute the following commands:

pacman -S --noconfirm base-devel msys2-devel mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain 
pacman -S --noconfirm svn git curl wget
pacman -S --noconfirm ca-certificates
pacman -S --noconfirm -cc

# Fix missing platform prefix for windres
[ -f /mingw64/bin/x86_64-w64-mingw32-windres.exe ] || ln -s /mingw64/bin/windres.exe /mingw64/bin/x86_64-w64-mingw32-windres.exe
[ -f /mingw32/bin/i686-w64-mingw32-windres.exe  ] || ln -s /mingw32/bin/windres.exe /mingw32/bin/i686-w64-mingw32-windres.exe

# Even when statically linking to libstdc++, it still tries to dynamically link to lib(win)pthread. On top of it, libtool is too
# stupid to recognize the semantics of -Wl,-Bstatic. This leaves one option: Removing the dynamic import libraries.
rm /mingw32/i686-w64-mingw32/lib/libpthread.dll.a
rm /mingw32/i686-w64-mingw32/lib/libwinpthread.dll.a
rm /mingw64/x86_64-w64-mingw32/lib/libpthread.dll.a
rm /mingw64/x86_64-w64-mingw32/lib/libwinpthread.dll.a

mkdir ~/prefix
echo 'export PATH="$HOME/prefix/bin:/mingw64/bin:/mingw32/bin:$PATH"' >>~/.profile
echo 'export PKG_CONFIG_PATH="$HOME/prefix/lib/pkgconfig"' >>~/.profile
echo 'export PATH="$HOME/prefix/bin:/mingw64/bin:/mingw32/bin:$PATH"' >>~/.bash_profile
echo 'export PKG_CONFIG_PATH="$HOME/prefix/lib/pkgconfig"' >>~/.bash_profile
source ~/.bash_profile

Download all required sources

In the user's home directory for MSYS2 C:\msys64\home\username, download the following files:

Build dependent libraries and patched FileZilla

Open an MSYS2 shell command window and run the following commands in sequence. This will take a while...

cd ~
tar xf gmp-6.0.0a.tar.xz
cd gmp-6.0.0
./configure --build=x86_64-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared --enable-fat
make && make install

cd ~
tar xf nettle-3.1.1.tar.gz
cd nettle-3.1.1
./configure --build=x86_64-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared --enable-fat
make && make install

cd ~
tar xf zlib-1.2.8.tar.gz
cd zlib-1.2.8
./configure --prefix="$HOME/prefix" --static
make && make install

cd ~
tar xf gnutls-3.4.8.tar.xz
cd gnutls-3.4.8
./configure --prefix="$HOME/prefix" --enable-static --disable-shared --build=x86_64-w64-mingw32 --with-included-libtasn1 --disable-doc --disable-guile --without-p11-kit --enable-local-libopts --disable-nls
make && make install

# The __declspec(dllimport) is needed for DLLs, but we're linking statically. It thus results in undefined references. Remove it.
sed -i 's/__declspec(dllimport)//' "$HOME/prefix/include/gnutls/gnutls.h"

cd ~
tar xf sqlite-autoconf-3100200.tar.gz
cd sqlite-autoconf-3100200
./configure --build=x86_64-w64-mingw32 --prefix="$HOME/prefix" --enable-static --disable-shared
make && make install

cd ~
unzip -q wxWidgets-WX_3_0_BRANCH.zip
cd wxWidgets-WX_3_0_BRANCH
./configure --prefix="$HOME/prefix" --enable-static --disable-shared --build=x86_64-w64-mingw32 --enable-unicode --without-libtiff --without-libjpeg --with-expat=builtin --with-libpng=builtin
make && make install

cd ~
tar xf libfilezilla-0.3.1.tar.bz2
cd libfilezilla-0.3.1
./configure --prefix="$HOME/prefix" --enable-static --disable-shared --build=x86_64-w64-mingw32
make && make install

cd ~
tar xf FileZilla_3.15.0.2_src.tar.bz2
mv filezilla-3.15.0.2 filezilla-3.15.0.2-wincred
cd filezilla-3.15.0.2-wincred
patch -p1 <../filezilla-3.15.0.2-wincred.patch
autoreconf -i
./configure --build=x86_64-w64-mingw32 --with-pugixml=builtin LDFLAGS="-static-libgcc -static-libstdc++"
make

# Stripping debug symbols
strip src/interface/.libs/filezilla.exe
strip src/putty/.libs/fzsftp.exe
strip src/putty/.libs/fzputtygen.exe
strip src/fzshellext/64/.libs/libfzshellext-0.dll
strip src/fzshellext/32/.libs/libfzshellext-0.dll

Generate the installer

Using the Windows explorer, browse to C:\msys64\home\username\filezilla-3.15.0.2-wincred\data.

Right click on file install.nsi and use "Compile Unicode NSIS Script" from the context menu. This creates the file FileZilla_3_setup.exe in the same directory.

Rename it as FileZilla-3.15.0.299-wincred-win64-setup.exe and you are done!