This page sums up SECURITY.md in plain words. That document is the authority, and has the detail.
Two things matter most:
- Treat an installer as being as private as the PC it came from. Do not post one, or send it to anyone you would not hand that PC to.
- Only run installers you built yourself, or got from someone you trust. An installer runs with full administrator rights, and only a signature can prove who made it.
An installer holds the app's files and settings, so it can hold anything the app keeps in them. The two options decide how much of you goes along.
With User Data off, which is the default, the build leaves out:
- the app's data folders;
- what the app remembers for you in the registry, such as recent files, saved sessions, and the servers you connected to;
- your PC's name, and whose data it was, from what the installer says about itself, and your account's name, profile folder, and SID from its warnings and lists. Paths are not changed: an app installed for your account alone is in your profile folder, so its paths name that folder, with your account's name in it. The last look reports that;
- personal shortcuts with their own arguments, and who wrote a scheduled task;
- what else was in your
Path, keeping only the app's entries; - the names and paths of data files that are not going in.
With License and Activation Data off, which is also the default, license files and values are not captured at all, including a serial number typed into a setup. Only their names are noted.
With User Data on, the installer also records the name of the PC and of the account whose data it holds. The installer's window shows the PC's name as Captured From, and the account's beside the User Data option, as "This holds the data of …".
What the app keeps in its own program folder, and in its machine-wide settings, goes as it is, whatever the options. An app can keep the PC's name there, and nothing looks for it. See What goes in an installer for the full list.
With User Data off, a build looks one last time through what the installer says about the app: its list of files and settings, and its registry settings, services, drivers, tasks, shortcuts, variables, reports, and restore plan. It looks for your account's name, your profile folder, the PC's name, and your account's SID. It looks in each way text is usually stored in a file, ignoring case, and for anyone's folder under Users and anyone's SID by their shape.
If it finds any, the done screen says so right after its first message and tiles, before anything else, by kind and by where, and never what. For example: "This package mentions the PC's name in registry values (2)." It changes nothing and stops nothing, because what it found may be what makes the app work. You decide whether to share that installer.
It does not see text stored in other ways, such as Base64, or a name on its own where nothing says it is one. It does not look in the app's own files, or in license files. A file it could not read is named, since it may say anything.
Values and files that look like a credential are never captured, whatever options you choose. That includes:
- a registry value, a service setting, an environment variable, or a command-line option named for a secret, such as
Password,ApiKey,Token, orClientSecret; - a value holding a connection string or web address with a password in it;
- a registry value that only Windows' own protection for a user's secrets (DPAPI) can read. Such data inside an app's own files is not recognised;
- files named for what they hold, such as
.env,id_rsa,credentials.json,passwords.txt, a browser's saved logins,*.pfx,*.kdbx, and*.ovpn; - a
.pem,.key,.crt, or.certhat holds a private key, or a.pemor.keythat cannot be read to tell.
They are named when you build, and in the installer, never with what they hold. Since none of them is in the installer, nothing can overwrite what the new PC has. You may have to enter them again.
The rules go by names and a few shapes of text. They cannot find every secret:
- They do not look inside the app's own files. A password in a settings file, a database, or a format of the app's own is copied like the rest of the file. That goes for everything User Data adds too.
- A value whose name does not say what it holds, such as
DataorBlob1, is captured unless its contents have one of the shapes the rules know. - Rules that caught more would break more apps, so names like
TokenizerPathandPasswordPolicyVersionare kept, and so is a file calledtokens.txt. - What is encrypted some other way than DPAPI is copied as it is.
So the list of what was left out tells you what was found, and nothing about what was not. Handle the installer accordingly.
The installer checks its package by hash before anything else. That catches damage, and changes by anyone who does not also update the hashes. But the hashes travel inside the installer, so anyone who can change the package can change them too.
What the installer does protect against:
-
A package that asks for too much. It refuses registry keys no app should write, and services, shortcuts, tasks, and startup items that run anything but the package's own files. Services, tasks, file types, and the like that belong to another app stay that app's, even with
--force. Files are the exception: with--force, and always in the installer's window, a file of the same name in the install location is replaced, even if another app's service runs it. A setting can also change what another app does, which no rule looks for. And what counts as the app's own keys goes by the name, publisher, and folder the package gives itself. See What the installer refuses. - A package from an odd or hostile drive. The rules are applied when installing, not only when building.
- Saying one thing and doing another. The list you agree to and the install go through one review. If what it would do has changed by the time you click Install, it installs nothing and shows the new list.
- Another program changing things mid-install. It unpacks to a folder only administrators can use, holds its own file open, checks each file again as it copies it, and will not write through a link.
What it cannot do: make a package safe. A package may run its own files with full rights, if it asks to. That is what installing an app is. So read the list in the installer's window before you click Install.
| File | Signed? |
|---|---|
The app, winappmigrator.exe, from 0.5.0 on |
Yes, with publisher Randy Northrup. Earlier downloads are not signed. |
| An installer you build | Only if you sign it yourself. Otherwise Windows shows "Unknown publisher". |
| The data file of an installer in two files | No. The signature on the .exe covers it. See Big apps. |
| The uninstaller an install leaves behind | Never, even when the installer was signed |
| WinAppMigrator Client, from 0.6.0 on | Yes, with publisher Randy Northrup. On a Windows 7 without Microsoft's 2020 root certificate, Windows cannot check a signature of this kind, and says the publisher is unknown. See Another PC over the network. |
The installer's window has a row, Installer, that says whether that file is signed and by whom, or "Not signed: publisher unknown". Trust that row, not the publisher name the package gives for the app.
Read the Installer row, not only the UAC prompt. A program already running on the PC could swap the installer's file in the instant before the installer opens it. The window then shows the signature of the file it really read. A command-line install prints nothing about a signature, so check the file with Get-AuthenticodeSignature before running it, and remember the same swap can happen after that check.
You can sign a finished installer with the project's script, scripts/sign.ps1. It uses Azure Artifact Signing. Its defaults are this project's own signing account, which only works for its owner, so anyone else gives their own endpoint, account, and certificate profile. It needs the .NET 8 runtime. Sign the .exe only.
Sign only installers of software you are allowed to pass on, because your name goes on them. A signature says what is in the package is what you built. It says nothing about what that package does. The details are in docs/signing.md.
Every installer starts with the same program, the installer stub, which installs whatever package comes after it. Windows does not include a signature's own storage area in what the signature covers. So if the stub were ever signed, anyone could hide their own package in that area, and the signature would still read as valid. This weakness is CVE-2013-3900, and Microsoft's fix for it is off by default. The result would be malware showing "Verified publisher" with this project's name.
So the stub is never signed, and three separate checks hold to that:
- The release workflow fails if the stub has a signature, and signs only the app and WinAppMigrator Client.
- Building an installer refuses a signed stub.
- The stub only reads a package from where a signature would cover it, never from inside the signature's area, and refuses anything after it.
The uninstaller is a copy of the stub, so it is never signed either, and its UAC prompt says "Unknown publisher". It is kept in a folder only administrators can change.
WinAppMigrator Client is signed, unlike the stub, because it never runs anything its own file carries. Whatever someone hid in its signature's storage area would never be looked at. What a signature could still be used for is to hand out the signed client beside a DLL of someone's own, for Windows to load into it under this project's name. So the client imports only DLLs Windows always loads from its own folder, and runs from a copy of itself in a folder only an administrator can change. See Releases and signing.
With Network PC…, the app reads another PC through WinAppMigrator Client, which runs there with administrator rights. What the app reads from it is treated as a drive from another PC is, with the same rules. The link adds this:
- Only a PC with the code can read anything. The six-digit pairing code is never sent over the network, and what is sent gives anyone listening nothing to work it out from. Anyone else on the network gets one guess each time they connect, 2 seconds apart, and the client makes a new code after five wrong ones. After 20 it lets nothing pair until it is started again.
- What crosses the network is encrypted and checked. A message changed, replayed, or reordered on the way is refused, and the link ends.
- The client only reads, and only inside its snapshot of the Windows drive. It never follows a link. On the old PC, it writes only its own record, the snapshot, two firewall rules, and the copy of itself it runs from, and removes them when it stops, or on its next run.
- While it runs, anyone on your local network can reach it, and see the PC's name and Windows. Only the code stands between them and the PC's files. Run it on a network you know, and stop it when the build is done.
- What the old PC says of itself is only shown, never trusted.
- The client is signed, as the app is, and its UAC prompt names Randy Northrup as its publisher. On a Windows 7 without Microsoft's 2020 root certificate, Windows cannot check a signature of this kind and says the publisher is unknown, and then nothing but its file shows it is the one the app saved. Either way, save it from the app, to a drive or folder only you can write to.
-
A DLL put beside the client is not loaded into it. It runs from a copy of itself in
%ProgramFiles%\WinAppMigrator Client, which only an administrator can change, and starts Windows' tools with an environment of Windows' own, not yours.
See Moving from a PC over the network, and the detail in SECURITY.md.
Treat any installer built by a version before 0.5.0 as private. Do not post it or pass it on. With or without the User Data option, those can hold:
- the name of the PC they were built on, and of the account that built them;
- what apps remember in the registry, such as recent files and the servers you connected to;
- the names and paths of data files that were not even going in;
- a serial number typed into a setup, even with the License option off;
- all of your
Path, and what other variables listed; - personal shortcuts with their arguments, and who wrote a scheduled task.
Nothing can take those out of an installer that has already been built. If you want one to share, build it again with 0.5.0 or later.
WinAppMigrator helps you move your own license. It reports whether each license looks tied to the old PC, and restores what can be restored. A license value in the machine-wide registry, and a license store tied to the hardware, are only named, never carried. It never decrypts license data, never gets around or imitates activation, and never imitates a hardware dongle. A license tied to the old machine may need activating again. Following the license terms of the software you move is up to you.
The app and the installer run with administrator rights, which makes them a target for tricking them into loading someone else's code. So they:
- load Windows' own libraries only from Windows' own folder;
- run Windows' tools by their full path, with Windows' folder taken from a place only administrators can change;
- take nothing about how a window is drawn from settings any program could change, except one that can only turn Direct3D 12 off;
- check that a runtime installer is signed by Microsoft, when it is downloaded and again just before it runs.
The full list is in docs/signing.md.
WinAppMigrator Client runs with administrator rights too, started from a USB drive or a shared folder. It imports only libraries Windows always loads from its own folder, runs from a copy of itself in a folder only an administrator can change, and starts Windows' tools by their full path, with an environment of Windows' own. See Why the client may be signed.
These matter most when deciding whether to run an installer. The detail is in SECURITY.md.
-
An install outside a protected folder stays changeable. A folder such as
D:\Appscan be changed later by other programs on the PC. For anything with a service or a driver, install underC:\Program Files. - A program already on the PC could, in theory, win a race against the installer's checks on such a folder, during the install. It has not been shown to be impossible.
- A file someone else can write to can be held open to make an undo fail. It is reported, and can be tried again.
- The installer's own file could be swapped in the instant before it opens it. That is why the Installer row matters.
Please report it privately, through GitHub's security advisories, not in a public issue. Include the version and the steps to reproduce it.
Only the latest release gets fixes.
Last changed 2026-11-11. Describes WinAppMigrator as of its latest release, 0.6.0.