One section per technique that real ClickFix campaigns use to get a command onto the clipboard.
Each test writes the same inert canary payload, then reads the clipboard back to show what landed.
The pill on each test indicates whether the technique fires a copy/cut
DOM event that an event-based detector can observe.
After any test, the readout below shows what is on the clipboard right now. Empty clipboard means the detector intercepted and cleared the copy. The payload appearing verbatim means the technique was not caught.
navigator.clipboard.writeText()
no copy eventThe dominant pattern in modern fake-CAPTCHA / “Verify you are human” lures.
Triggered from a button’s click handler; the user gesture is the button click itself,
so no permission prompt fires. No DOM selection, no copy event.
navigator.clipboard.writeText(PAYLOAD)
navigator.clipboard.write() with single-format ClipboardItem
no copy eventSame delivery vector, richer API. Seen in newer kits that want to set non-text formats.
Single text/plain blob here, same payload.
navigator.clipboard.write([
new ClipboardItem({ 'text/plain': new Blob([PAYLOAD], { type: 'text/plain' }) })
])
navigator.clipboard.write() with multi-format ClipboardItem (HTML decoy + plain payload)
no copy eventUsed by kits that try to fool clipboard managers / preview tooling that display HTML: the visible HTML
form is innocuous (e.g. a verification code), the text/plain form is the command.
Terminal pastes always take plain text.
navigator.clipboard.write([
new ClipboardItem({
'text/plain': new Blob([PAYLOAD], { type: 'text/plain' }),
'text/html': new Blob(['<b>Verification code: 4F7-2A1</b>'], { type: 'text/html' })
})
])
document.execCommand)<textarea> + execCommand('copy')
fires copy eventThe pre-navigator.clipboard standard technique. Still ubiquitous because many ClickFix
kits were written when it was canonical, and because it works as an automatic fallback when the async API is
blocked. Programmatic selection of an off-screen <textarea>, then
document.execCommand('copy').
const ta = document.createElement('textarea');
ta.value = PAYLOAD;
ta.style.position = 'fixed'; ta.style.opacity = '0';
document.body.appendChild(ta);
ta.select();
document.execCommand('copy');
ta.remove();
<div> + execCommand('copy')
fires copy eventVariant of #4 that selects via Range + Selection instead
of a form element. Used by some kits to avoid focus-stealing on mobile or to copy from an existing visible node.
const div = document.createElement('div');
div.textContent = PAYLOAD;
div.style.position = 'fixed'; div.style.left = '-9999px';
document.body.appendChild(div);
const range = document.createRange();
range.selectNodeContents(div);
const sel = window.getSelection();
sel.removeAllRanges(); sel.addRange(range);
document.execCommand('copy');
sel.removeAllRanges();
div.remove();
contenteditable + execCommand('cut')
fires cut eventLess common but in the wild. Same delivery, but uses cut on a
contenteditable region. Detectors that only listen to copy
and not cut miss this.
const div = document.createElement('div');
div.contentEditable = 'true';
div.textContent = PAYLOAD;
div.style.position = 'fixed'; div.style.opacity = '0';
document.body.appendChild(div);
const range = document.createRange();
range.selectNodeContents(div);
const sel = window.getSelection();
sel.removeAllRanges(); sel.addRange(range);
document.execCommand('cut');
div.remove();
clipboardData during the user’s copy event
fires copy eventThe page lets the user select visible, benign text (a “verification code”, an order number,
a wallet address) and registers a copy listener that replaces the clipboard payload
with the command. The detector that reads document.getSelection() sees the benign
text and approves; the clipboard receives the command. Common against crypto wallets / bank account fields;
used by some ClickFix variants too.
Select the text inside the dashed box, then press Ctrl/⌘+C:
oncopy attribute / inline handler (variant of #7)
fires copy eventSame idea as #7 but the hijack is attached as an inline DOM attribute on the source element rather than a
addEventListener call. Selecting and copying the box below replaces the clipboard
with the payload. Some content scripts that only look at addEventListener-attached listeners (e.g. via debug
APIs) miss this; behaviourally it’s identical.
DataTransfer on dragstart
fires dragstart, not copyA few lures instruct users to “drag this verification token into the Run dialog” (which doesn’t
actually accept drops, but the same UI works on terminal apps and chat windows). The data is set on the
DataTransfer object of a dragstart event — no
copy event ever fires, so clipboard-event detectors don’t see it.
Drag the chip below to a text field to see the payload appear:
navigator.clipboard.writeText / .write (page-world / MAIN-world script).copy event listener that reads the actual clipboard payload (event.clipboardData.getData('text/plain')) rather than getSelection().cut.getSelection() in the copy handler; reading clipboardData instead catches them.dragstart hook on DataTransfer.setData.