3

I plan to run potentially dangerous applications (browser, etc.) on a separate X-server, but since each server has its own clipboard, it is impossible to copy the link / text from one window to another.

Most articles suggest doing this using scripts using xclip and other similar utilities.

But how to CORRECTLY create a common clipboard so as not to accidentally create a new vulnerability?

2 Answers 2

2

I use xclipsync. It works in 98%. In 2% I'm doing this:

On dislpay :0 run copyq. On display :1 run parcellite. To sync clipboard i use

copyq add $(parcellite) 

or to backward

copyq read | parcellite -c 

It works 100%! :-)

1
  • Better solution is maybe use two sessions copyq and this script gist.github.com/hluk/… Commented Feb 25, 2021 at 14:00
-1

NOTE: Updating answer to reflect change of strategy - instead of running Xephyr on a server/container, I am running it on host/main-use environment. The reason for that is that running Xephyr on the server/container is like putting a lock on an inside door instead of the front door - bad actors would go around the inside door and access the clipboard through the X pipe remote socket directly.

Facing the same problem of clipboard vulnerability, I approached it by running a Xephyr on the host (my personal workspace), and forwarding X from the server-on-container(s) to the local Xephyr.

The Xephyr is running on display ':2' while my personal workspace windows and browser are running on the default display ':0'. These two displays do not share a clipboard - each has it's own clipboard. That is the only way to prevent snooping of my personal workspace clipboard on display ':0'. Then I have hot keys set up (e.g., function keys), one to transfer the clipboard content from ':0' to ':2', and another for ':2' to ':0', so allowing complete control.

In shell script the code could look like

xsel --display :0 --clipboard -o | xsel --display :2 --clipboard -i 

although I am using javascript as shown at the bottom of this post.

Shell script to start up the X forwarding could look something like this

Xephyr <args> :2 DISPLAY=:2 ssh -X -R 44713:localhost:4713 user@container <<EOF DISPLAY=:10 PULSE_SERVER=tcp:localhost:44713 openbox --startup firefox EOF 

although I am using a javascript program to do it.

Here is the javascript code for copying between ':0' and ":2" which is mapped to by hot keys. You can see it pops up a transient message box to confirm it worked.

#!/usr/bin/env node `strict`; const child_process = require('child_process'); // TODO: write unviewable error messasges to system log function notifySend(title, msg){ title = title.replace(/"/g, '\\"'); msg = msg.replace(/"/g, '\\"'); //msg = msg.replace(/'/g, '\\'') try { child_process.execSync(`notify-send "${title}" "${msg}"`); } catch(e) { console.log(`system call "notify-send" failed with ${e.message}`); } } async function clipXfer(fromDispNum,toDispNum){ var clipValue; let cmd1 = `xsel --display :${fromDispNum} --clipboard --output`; let cmd2 = `xsel --display :${toDispNum} --clipboard --input`; try { clipValue = child_process.execSync(cmd1, { encoding: 'utf-8' }); } catch(e) { throw Error(`Display ${fromDispNum} clipboard is empty`); } await new Promise((resolve, reject)=>{ // eslint-disable-next-line no-unused-vars var proc = child_process.exec(cmd2, (error, stdout, stderr) => { //if (stdout) console.log(stdout); //if (stderr) console.log(stderr); if (error) { reject(Error(`${error.message}`)); } resolve(); }); if (!proc.stdin.write(clipValue)) reject(Error('clipToCont(), pipe write failed')); proc.stdin.end(); }); } async function main() { let argOff=2; if (process.argv.length-argOff<2) throw Error('clip-xfer requires two arguments: fromDispNum, toDispNum'); let fromDispNum = process.argv[argOff]; let toDispNum = process.argv[argOff+1]; argOff+=2; let f = (outcome)=>{ notifySend("clipXfer", `${fromDispNum} => ${toDispNum} ${outcome}`); }; await clipXfer(fromDispNum,toDispNum) .then(f('SUCCESS')) .catch((e)=>{f(`FAILURE, ${e.message}`); throw e;}); } //console.log(process.argv); //console.log(process.env); main() .then(()=>{process.exitCode=0;}) .catch((e)=>{ console.log(e); process.exitCode=1; }); 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.