Copy-paste / hidden-text attacks

What you copy is not always what you paste.

You copy one harmless-looking command from a web page. What lands in your clipboard can carry extra lines and invisible characters you never saw, and a single trailing newline can run them the instant they hit an unprotected terminal.

hidden lines / invisible characters / auto-run on paste

What is this? When a website shows you a command to run, you trust that the text you see is the text you copy. It isn't always. A page can hide extra text inside the snippet (off-screen, zero-width, or disguised) so your clipboard receives more than your eyes did. This page shows the trick safely (every hidden payload here is a harmless echo) and the simple habit that defeats it.

What the page shows you

One tidy line: an apt install from a README, a git config from a setup guide, a fix pasted from a Stack Overflow answer or a chatbot. It looks like exactly what you need, so you select it and hit copy.

What your clipboard receives

Possibly more: an appended command hidden off-screen, invisible Unicode wedged into a word, or a trailing newline that presses Enter for you. The terminal runs bytes, not the picture you looked at.

Seen in the wild

The copy-paste gap is not hypothetical. Two variants are in active, documented real-world use right now.

Seen in the wild Paste-and-run

"ClickFix": the fake error that asks you to paste

A page shows a fake CAPTCHA or "fix this error" box and tells you to press Win+R (or open a terminal) and paste. The command was silently pre-loaded onto your clipboard by the page, so you run the attacker's installer thinking you are just proving you are human.

Backdoor path: the pasted one-liner fetches and runs an infostealer or RAT (Lumma Stealer, DarkGate, NetSupport, AsyncRAT), handing over your credentials, session, and a foothold.

Seen in the wild: named by Proofpoint, who coined "ClickFix" from a 100,000-message campaign by the broker TA571. It is now its own MITRE ATT&CK technique (T1204.004), ranked by Red Canary as the #2 initial-access vector of 2025, and adopted by nation-state actors: Kimsuky (DPRK), MuddyWater (Iran) and APT28 (Russia). Microsoft, which tracks the technique too, reports campaigns hitting thousands of devices daily.

Reproduce · sandbox VM only; the clipboard-preload + paste-and-run step -- the fake CAPTCHA page that delivers it is social engineering, not a static fixture · view the PoC on GitHub →
base64 -d poc/paste-trailing-newline-autoexec/payload.b64 | wl-copy # then paste into a throwaway shell
Mitigation · never paste a web-supplied command straight into a shell -- read the clipboard first
wl-paste | unicode-show # see exactly what will run, hidden bytes and all
Seen in the wild Clipboard hijack

Clipper malware: your clipboard, quietly rewritten

Malware on the machine watches the clipboard and swaps what you copied for something else (classically a cryptocurrency wallet address replaced with the attacker's look-alike), so the value you paste is not the value you copied.

Backdoor path: you copy a wallet address and paste it to send funds; the money goes to the attacker. The swap happens silently between copy and paste, with no visible change.

Seen in the wild: a long-running malware class: CryptoShuffler (2017, ~$140k stolen) and the Laplas Clipper malware-as-a-service (2022), which mints a look-alike address matching the first and last characters of yours. More reporting.

Reproduce · sandbox VM only; a benign hand-run stand-in for the outcome -- real clipper malware does the swap automatically, watching for wallet-shaped strings. No resident monitor is shipped here; the values are obvious DEMO placeholders.
printf 'bc1q-DEMO-your-own-wallet' | wl-copy # what you meant to copy
printf 'bc1q-DEMO-ATTACKER-lookalike' | wl-copy # a "clipper" silently overwrites it
wl-paste # you paste the attacker address, not yours
Mitigation · no neutralizer sees a content swap -- verify the pasted value end to end before you act on it
wl-paste # read the whole address back; confirm it out-of-band

The trick

A rendered snippet and its underlying text are two different things. Three ways they come apart on the way to your shell.

Seen in the wild Auto-run on paste

The paste that presses Enter for you

Modern terminals and shells defend against this by default: on a current emulator with interactive bash (>= 5.1, Dec 2020), zsh or fish, a pasted newline is held on the command line for you to review -- "bracketed paste," on by default. But it is not universal. It fails wherever the reader does not honour it: bash before 5.1, minimal shells (POSIX /bin/sh (dash), busybox ash), raw REPLs and readers that never request it (cat, a language REPL, a serial or recovery console), ssh into an old host, or an app that turns the mode off. There, a snippet ending in a newline still submits the moment it lands -- and it can be bypassed on unpatched terminals by crafted clipboard content (CVE-2021-31701).

The catch: on such a reader, combined with a hidden line, there is no pause to notice anything: the copy, the paste, and the execution are one motion.

Backdoor path: no hidden line is even needed -- on a reader without bracketed paste, a visible command that ends in a newline runs the moment it lands, before you can cancel, and any multi-line paste executes every line in sequence.

Seen in the wild: paste-and-run is the payload step of ClickFix (MITRE ATT&CK T1204.004), an active initial-access campaign detailed above.

Reproduce · sandbox VM only; a pasted attack, not cat - then paste (Ctrl-Shift-V) into a throwaway terminal · view the PoC on GitHub →
base64 -d poc/paste-trailing-newline-autoexec/payload.b64 > paste.payload
xclip -selection clipboard < paste.payload # X11
wl-copy < paste.payload # Wayland
Mitigation · bracketed paste (default on bash >= 5.1, zsh, fish) holds the newline for review; on readers that lack it, inspect first
wl-paste | unicode-show # see the trailing newline before it can submit
Proof of concept Hidden line

The extra line you never saw

Text placed off-screen with CSS, or tucked into a zero-height element, is still part of what you select and copy. The page shows one command; the clipboard gets two. Like invisible ink on a page you photocopy: the copy captures what your eyes skipped.

The catch: if the hidden portion ends in a newline, a reader without bracketed paste submits it the moment you paste and the second command runs before you have read the first. Modern bash/zsh/fish hold it by default (see Auto-run on paste) -- older or minimal shells, REPLs and old SSH hosts do not, so do not rely on it.

Backdoor path: the hidden line is a real command (a curl | sh installer, a key exfiltration); on an unprotected reader its trailing newline runs it the instant you paste, before your eyes reach the harmless line you meant to copy.

Proof of concept: the page-side hidden-copy trick was demonstrated as pastejacking (2016; no CVE -- inherent browser clipboard behavior). Its active in-the-wild social-engineering cousin, ClickFix, is above.

Proof of concept Invisible characters

Characters that ride along unseen

Zero-width and control characters copy perfectly but display as nothing. A command that reads pip install requests can carry an invisible break, or a look-alike letter, so the thing your shell runs is not the thing you read: an invisible extra character wedged inside a word.

The catch: the payload survives a glance, a code font, even a careful proofread. It is not on the screen to be seen.

Backdoor path: the look-alike or zero-width character binds the command to a different target -- a typosquatted package name, a different host -- so the shell fetches attacker code while the text still reads as the trusted one.

Proof of concept: the invisible-character class was formalized as Trojan Source (CVE-2021-42574); research disclosure, no documented in-the-wild use of this copy-paste vector.

Live demo: completely safe

Copy the line below and paste it into a text editor (not a terminal). A second line you never saw comes with it. Here it is only an echo, but it could have been anything.

Proof of concept Try it: echo only, nothing runs

Copy one line. Get two.

what the page shows
echo "installing helper..." echo "GOTCHA: this second line was hidden in the copy; imagine a real command here"

No JavaScript needed: click the command once (that selects both lines, the hidden one included) then press Ctrl+C (Cmd+C on Mac). The button is only a shortcut; the pane at right shows exactly what you get either way.

what your clipboard receives
echo "installing helper..."
echo "GOTCHA: this second line was hidden in the copy; imagine a real command here"

The catch: the second line is real text in this page, positioned off-screen so you cannot see it. Your eyes skip it; the clipboard does not. Both lines here are harmless echos: swap the second for something destructive and the lesson is the same.

Proof of concept: the web-page version of this (shown text differs from the copied text via a JavaScript copy handler) was demonstrated as "pastejacking" by Dylan Ayrey in 2016 (press). There is no CVE: it is inherent browser clipboard behavior, not a product bug. What went wild is the social-engineering cousin above.

Proof of concept Try it: invisible character

Copy a clean-looking command. Get a hidden character.

what the page shows
pip install requ​ests

Looks exactly like pip install requests. Select and copy it, then paste it into the Analyze page (or run unicode-show on it) and watch the hidden character appear.

what your clipboard receives
pip install requU+200Bests

The catch: a U+200B ZERO WIDTH SPACE sits inside the package name. The string is not requests but a look-identical typosquat that a package index can hold as a separate name. It survives a glance, a code font and a careful proofread, because it is not on the screen to be seen - only a byte-level tool surfaces it.

Backdoor path: the invisible byte makes the copied text bind to an attacker-registered look-alike package, so pip install pulls their code while the line you read names the trusted one.

Proof of concept: the invisible-character class was formalized as Trojan Source (CVE-2021-42574); no documented in-the-wild source-code use.

Try it yourself

Every paste trick here is a real, canary-forked test fixture. Reproduce one in a throwaway sandbox VM, watch a plain terminal auto-run it - then see it held for review, or x-rayed, instead.

Clone the corpus (read SAFETY.md first) and list every class:

git clone https://github.com/secure-terminal/terminal-poc-corpus
cd terminal-poc-corpus && ls poc/

Reproduce a pastejacking payload, then put it on the clipboard to paste (sandbox VM only):

base64 -d poc/paste-trailing-newline-autoexec/payload.b64 > paste.payload
xclip -selection clipboard < paste.payload # X11
wl-copy < paste.payload # Wayland

What you see vs what runs. Paste it into a plain terminal and the hidden line auto-runs; paste it into secure-terminal's review bar and it is held - every hidden byte named - before a byte reaches the shell. Or x-ray any command you copied first with the Analyze tool. Every PoC doubles as a test fixture: index.json records its class and expected-safe behaviour, and the always-on terminal-resilience-tests suite checks them all.

How to copy commands safely

Never paste a copied command straight into a terminal. Route it through a step where hidden bytes become visible first: the same safe-text tools used for logs and diffs.

01

Paste into an editor

Paste into a plain text editor and save to a file, never straight into the shell. Now the bytes are sitting still, not running.

02

Scan for hidden bytes

Run unicode-show (or text-safety-scan) on the file. Every invisible, control or look-alike character is named with its codepoint: the hidden line stops hiding.

03

Read it, then run it

Display it with stcat so escapes are inert, read every line you actually have, and only then run it: deliberately, not by a stray newline.

All of these ship in Kicksecure's helper-scripts and are shown side by side on the terminal page. The attack and this workflow are documented on the Kicksecure wiki.

FAQ

Is the demo actually safe?

Yes. Both the visible line and the hidden line are echo statements: they only print text. Nothing here runs on its own, and even if you did paste it into a terminal it would just print two harmless messages. The point is to show the divergence, not to exploit it.

Why would a paste run on its own?

A terminal treats a newline the same whether you typed it or pasted it: as "run this now". A snippet that ends in a newline (or contains several lines) therefore executes on paste. Bracketed-paste mode (default in many modern terminals) holds the input instead, but it is not universal, so the safe habit is to never paste command text directly into a shell.

How do I copy commands safely?

Paste into a text editor first, scan the file with unicode-show or text-safety-scan, view it with stcat, read every line, and only then run it. See the full safe-copy steps above.

How is this related to the other pages?

Same root cause, different moment. On git diffs lie the deception happens while you review code; with cat lies too it happens while you display a file or log; here it happens while you copy and paste into a shell. In every case, what is rendered is not what is really there, and the same neutralize / surface / read-first defenses apply.

Where is this documented?

Kicksecure's Hidden Text Attacks section covers the copy-paste case and the safe workflow. The invisible-character class was formalized as Trojan Source (CVE-2021-42574).

Was this built with AI?

Yes: this page and its demonstrations are AI-assisted. See also status of human review.