Your Windows Clipboard Is Unprotected
So, I just want to explain some problem of the Windows clipboard… It’s completely unprotected. I mean, any process with user privileges is able to intercept your copied content silently. Let’s try to do it in practice and think about how to live with this knowledge?
Windows clipboard under hood
What happens when you copy some text (or other data)? It goes into shared memory managed by user32.dll. We’ll skip the part with allocation and everything, today we’re here to intercept the clipboard, not to study the Windows architecture deeply, right? So, when the copied information goes to the clipboard, it also receives tags to mark the copied data type. For example, it will be CF_UNICODETEXT for Unicode text and CF_BITMAP for bitmaps. The recipient (the application that will receive the copied data) will use these tags to decide what to do with the data. This procedure is highly abstracted in production ready GUI frameworks, so you don’t need to think about processing it, you just won’t be able to insert bytes of your cat photo into the clipboard as bytes in the text field of the app. When the receiving application gets the data from the clipboard, it uses GetClipboardData() to do it and uses GlobalLock() to read the data safely from the shared memory and copy it to its own private buffer.
Making the interceptor
Long story short, too much theory… “Shared” means “shared”, so let’s make a program that will silently intercept everything that was placed on the clipboard! Of course we will use Rust, my favorite beloved language! Since it’s after midnight, April, 2, we will use C, no jokes. Look at the simple interceptor I’ve already made, then we will see to the code closer.
To compile:
Very simple program, very tiny binary. How does it work? Here is the workflow:
- Intercepting updates of the clipboard (WM_CLIPBOARDUPDATE)
- Skipping all but Unicode text (CF_UNICODETEXT)
- Locking shared memory
- Reading buffer
- Printing intercepted text
- Unlocking memory
Crucial parts of the code
We are interested in Unicode text only, so just do nothing if something else comes to the clipboard:
When reading the shared memory, we should lock it to avoid problems if it changes during reading:
We should ask user32.dll to notify our process if anything comes to the buffer. It never refuses to help and will be happy to notify our process:
After we’re done, it’s time to collect our toys and go home, so don’t forget to say “Goodbye!” to the clipboard by RemoveClipboardFormatListener(hwnd).
The problem
What is all of this about? Any running application has the possibility to silently read your clipboard through the standard WinAPI - with just “user” privileges. Always keep this in mind when you launch some centennial software, even without administrator privileges. It can always result in surprises, especially if you are using a password manager and copying your passwords through the clipboard.
Solution
You might say: “Wait, man, but we can tag copied content with ExcludeClipboardContentFromMonitorProcessing and it won’t be able to be intercepted!”. No, it doesn’t work like that. This tag literally works the same way as your lunchbox with a sticker “DO NOT TOUCH” in the public fridge. Everyone will read it, but the final decision about whether to touch it or not is absolutely up to the person who has access to the fridge. This is not a prohibition, but a polite request only. Following the tag or ignoring it is exclusively up to the conscience of the clipboard interceptor or the lunchbox thief.
Basically, there is no solution. Technically, you can spend some time and write your own clipboard manager, but the system one has SO DEEP integration that you will break everything in your system. Let’s stay in reality: you will not be able to integrate your own system in the same way as the native clipboard buffer is integrated.
P.S. I just attached comment system to the blog. Feel free to leave your comments and suggestions.