How to clear both clipboards securely in Gnome, from Python?
Asked Answered
K

3

5

Gnome desktop has 2 clipboards, the X.org (saves every selection) and the legacy one (CTRL+C). I am writing a simple python script to clear both clipboards, securely preferably, since it may be done after copy-pasting a password.

The code that I have seen over here is this:

# empty X.org clipboard
os.system("xclip -i /dev/null")  

# empty GNOME clipboard
os.system("touch blank")  
os.system("xclip -selection clipboard blank")  

Unfortunately this code creates a file named blank for some reason, so we have to remove it:

os.remove("blank")

However the main problem is that by calling both of these scripts, it leaves the xclip process open, even after I close the terminal.

So we have 2 problems with this option:

1) It creates a blank file, which seems like a flawed method to me

2) It leaves a process open, which could be a security hole.

I also know about this method:

 os.system("echo "" | xclip -selection clipboard")  # empty clipboard

However this one leaves a \n newline character in the clipboard, so I would not call this method effective either.

So how to do it properly then?

Kathaleenkatharevusa answered 28/1, 2018 at 19:21 Comment(3)
I'd recommend having a look at clipster which is an X clipboard manager written entirely in python, which will either do what you want, or provide enough code to help you solve the problem.Malm
Try echo -n instead of echo ""Postrider
@DavisHerring please write your suggestion as answer, I am curious about how to do it with subprocess. I was only familiar with the os package, but I assume it was not the most efficient way of doing it.Kathaleenkatharevusa
K
0

I have figured out:

#CLIPBOARD cleaner
subprocess.run(["xsel","-bc"])

#PRIMARY cleaner
subprocess.run(["xsel","-c"])

This one cleans both buffers, and leaves no zombie processes at all. Thanks for everyone who suggested some of them.

Kathaleenkatharevusa answered 29/1, 2018 at 19:59 Comment(4)
Do you even need input with -c?Porshaport
@DavisHerring How do you suggest it? Please edit the answer if you found a better way.Kathaleenkatharevusa
My answer already contains xsel -c with no input="". You’re quite right that adding -b targets CLIPBOARD; I took that to be obvious from the man page.Porshaport
@DavisHerring yes you are correct, the input is not needed, works fine this way too.Kathaleenkatharevusa
T
4

I know three ways to clear the clipboard from Python. First using tkinter:

try:
    from Tkinter import Tk
except ImportError:
    from tkinter import Tk
r = Tk()
r.withdraw()
r.clipboard_clear()
r.destroy()

Second with xclip, but I use xclip like this:

echo -n | xclip -selection clipboard

Does it create a new line?

Finally, it's possible to user xsel:

xsel -bc
Trifocals answered 28/1, 2018 at 19:56 Comment(3)
The echo command seems good now, no new lines. What is the difference between doing it like that or throug the xsel command?Kathaleenkatharevusa
Also the tkinter solution requires that package installed, it's not installed by default, I could install it ,but I'd prefer not to at this moment. Also these only clear the legacy clipboard ,but leave the X.org one intact.Kathaleenkatharevusa
By examining the man pages, I could see no significant security improvement either one has over the other. xsel has less dependencies tho, while xclip seems to have more features.Trifocals
P
4

Misconceptions

  1. GNOME doesn't "have clipboards"; X11 has selections and cut buffers. There are more than 2 of them, but mostly we worry about the selections PRIMARY and CLIPBOARD. Neither of them is "legacy".
  2. You can't "securely" clear these (by writing something else into the memory they occupy), since they aren't stored in your process. Cut buffers (which are obsolete) are stored in the X server, and selections are stored (if anywhere) in the process providing them. (If there is a clipboard manager running, they may be stored in several places and be impossible to kill completely.)
  3. xclip has to leave a background process running to serve the selection it sets to any processes requesting it. It's mostly useless when the selection is empty, but it does go away as soon as anything else is selected/copied, and it is surely not a security risk.
  4. Never use os.system (or system in any language), except to run a shell command specified by the user (like ! in less). It uses the shell (specifically, /bin/sh), which (because it is meant for interactive use) requires various kinds of quoting to avoid misinterpretation of generated input, it affects signal handling, it can't set up the child's open files directly, and it makes it all too easy to ignore the exit status of the child.

Tools

  1. There of course exist Python bindings for Xlib, including manipulating selections. Probably overkill if selection-clearing is your only use case.
  2. Tkinter, as mentioned, probably supports this (Tk certainly does), but I haven't found a reference for it.
  3. xclip and xsel, as mentioned, are widely available (both are in the Ubuntu repositories, for instance). You run external programs in Python using subprocess; in Python 3.5 or better it looks like one of

    subprocess.run("xclip",stdin=subprocess.DEVNULL)
    subprocess.run(["xclip","-selection","clipboard"],input="")
    subprocess.run(["xsel","-c"])
    

    (The choice between stdin and input matters more if you don't immediately wait on the program to exit.) xsel has an explicit --clear option, which avoids the need for input and a background process.

With any of these, you'll need to treat each of the two common selection types.

Porshaport answered 29/1, 2018 at 6:39 Comment(2)
A big honking +1 for the "misconceptions" section. The Unix clipboard is a huge mess (and a barely working one FWIW), but there is no such a thing as a "gnome legacy clipboard".Trantrance
The script works, but the processes remain hanging in there: https://mcmap.net/q/2032852/-how-to-run-a-process-and-quit-after-the-script-is-over/9213435Kathaleenkatharevusa
K
0

I have figured out:

#CLIPBOARD cleaner
subprocess.run(["xsel","-bc"])

#PRIMARY cleaner
subprocess.run(["xsel","-c"])

This one cleans both buffers, and leaves no zombie processes at all. Thanks for everyone who suggested some of them.

Kathaleenkatharevusa answered 29/1, 2018 at 19:59 Comment(4)
Do you even need input with -c?Porshaport
@DavisHerring How do you suggest it? Please edit the answer if you found a better way.Kathaleenkatharevusa
My answer already contains xsel -c with no input="". You’re quite right that adding -b targets CLIPBOARD; I took that to be obvious from the man page.Porshaport
@DavisHerring yes you are correct, the input is not needed, works fine this way too.Kathaleenkatharevusa

© 2022 - 2024 — McMap. All rights reserved.