Skip to main content

Bracketed paste

AI-Generated Content
This page was generated with the assistance of AI and may contain inaccuracies. It is intended as a placeholder for future human verification. If you spot issues ahead of its initial review, please report them on GitHub!
Experimental

Bracketed Paste (Mode 2004) is a DECSET/DECRST mode that causes the terminal to wrap pasted text with start and end marker sequences, allowing applications to distinguish typed input from pasted text.

Syntax​

CSI ? 2004 h    DECSET — Enable bracketed paste mode
CSI ? 2004 l DECRST — Disable bracketed paste mode
Formal syntax
DECSET-mode2004 = 0x1b, "[", "?", "2", "0", "0", "4", "h" ;
DECRST-mode2004 = 0x1b, "[", "?", "2", "0", "0", "4", "l" ;

Description​

Mode 2004 is an XTerm extension that provides a mechanism for applications to detect when text is being pasted from the clipboard rather than typed by the user.

  • Set — Pasted text is bracketed with start and end markers.
  • Reset — Pasted text is delivered as-is, indistinguishable from typed input. This is the default.

Bracket sequences​

When Mode 2004 is enabled and the user pastes text, the terminal wraps the pasted content:

SequenceHex bytesMeaning
CSI 200 ~1b 5b 32 30 30 7eStart of pasted text
CSI 201 ~1b 5b 32 30 31 7eEnd of pasted text

The pasted text appears between these markers:

\e[200~<pasted text>\e[201~

Security: paste injection prevention​

Without bracketed paste, a malicious clipboard payload can inject arbitrary commands. For example, pasting the following into a shell would execute the command immediately:

ls\nrm -rf /\n

With bracketed paste enabled, the shell (or application) receives the start marker, recognizes the content as pasted, and can treat it as literal text rather than executing embedded newlines as command separators.

This is one of the most important security features in modern terminal emulators and is widely supported by shells (bash, zsh, fish) and editors (vim, neovim).

Shell integration​

Modern shells handle bracketed paste natively:

  • Bash (5.1+) — Enabled by default in readline
  • Zsh — Enabled by default via the bracketed-paste-magic widget
  • Fish — Enabled by default

When these shells detect the paste brackets, they insert the pasted text into the editing buffer without executing it, allowing the user to review the content before pressing Enter.

note

Applications must strip or filter the bracket sequences from the pasted content. If the start/end markers appear in the pasted text itself, they should be sanitized to prevent bracket escape attacks.

Examples​

printf '\e[?2004h'   # Enable bracketed paste mode
printf '\e[?2004l' # Disable bracketed paste mode

# When the user pastes "hello world", the application receives:
# \e[200~hello world\e[201~

# A simple read loop that detects paste brackets:
printf '\e[?2004h'
# Read input and look for \e[200~ to detect paste start
# Look for \e[201~ to detect paste end
printf '\e[?2004l'

Specifications​

SpecificationSection
XTerm ctlseqs—

Terminal support​

TerminalSupportVersionNotes
Terminal Emulators
Alacritty✓Yes
Bobcat??Not explicitly configured in Bobcat. TerminalCtrl may support this, but cannot confirm from Bobcat's code.
contour✓v0.3.10.257Implemented as DECMode::BracketedPaste at primitives.h:688, handled in Terminal.cpp:2366
foot✓Yes
Ghostty✓v1.0.0
iTerm2✓v20260216-nightlyCan be disabled via allowPasteBracketing setting
Kitty✓Yes
Konsole✓YesMODE_BracketedPaste implemented
mintty✓YesImplemented at src/termout.c:2557
mlterm✓rel-3_8_2
PuTTY✓0.72
Rio✓v0.1.13
rxvt-unicode✓9.01Requires ENABLE_FRILLS (default on)
st✓0.5
terminology✓v0.5.0Uses bracketed_paste flag
VT100✗No
VTE✓Yes
WezTerm✓Yes
Windows Terminal✓YesXTERM_BracketedPasteMode at adaptDispatch.cpp:1876-1878
xterm✓238Requires OPT_PASTE64 compile flag (enabled by default)
xterm.js✓3.0.0
Multiplexers
cy✓v1.10.0
GNU Screen✓v.4.3.0Added in commit c389013 (2013)
tmux✓1.7
tuios✓v0.0.15
Zellij✓v0.31.2

See also​