UTF-7 UTF-7 (7-bit Unicode Transformation Format) Unicode
A mostly-obsolete 7-bit-safe Unicode encoding designed for old email systems — now largely remembered for the XSS security issues it caused.
What it is
UTF-7 is a Unicode encoding designed to be safe for transmission through systems that could only reliably handle 7-bit ASCII — most notably older email infrastructure (SMTP historically had 7-bit limitations before 8BITMIME and MIME extensions became universal). ASCII characters pass through mostly unmodified; everything else gets encoded using a modified Base64 scheme wrapped in +...- escape sequences.
As of 2026, UTF-7 is largely obsolete for its original purpose — MIME (with Quoted-Printable or Base64 content-transfer-encoding) and modern 8-bit-clean email transport have made UTF-7 unnecessary for email, and it's essentially never used for general web/application data. It's mostly relevant today as a historical curiosity and, less pleasantly, as a source of a specific class of security vulnerabilities discussed below.
Byte structure
| Content | Encoding |
|---|---|
| Most printable ASCII (letters, digits, most punctuation) | Passed through directly, unmodified |
| Non-ASCII Unicode characters | Converted to UTF-16, then encoded using a modified Base64 alphabet, wrapped between a + (start) and - (end, sometimes omitted if unambiguous) |
A literal + character in the original text |
Encoded specially (as +-), since + is UTF-7's own escape-sequence marker |
This design lets UTF-7 stay entirely within the 7-bit ASCII range (values 0-127) even while representing arbitrary Unicode content, at the cost of noticeably more complex encode/decode logic than UTF-8.
Why your text is garbled (symptom → cause)
| Symptom | Likely cause |
|---|---|
Text shows literal +...- sequences instead of the intended characters |
Content is UTF-7-encoded but being displayed/parsed as plain text rather than decoded |
A stray +- appears where a plus sign should be |
Correct UTF-7 escaping of a literal + character — expected behavior, not corruption, if you're intentionally working with UTF-7 |
| Modern email client fails to properly interpret an old archived email | Old email genuinely encoded in UTF-7 (per its original MIME charset declaration) being read by tooling that doesn't fully support decoding it |
Compatibility & gotchas — and a real security issue
- UTF-7 played a role in a well-documented class of XSS (cross-site scripting) vulnerabilities. Some older versions of Internet Explorer would auto-detect and interpret content as UTF-7 even without an explicit charset declaration, under certain conditions. Attackers exploited this by crafting input that looked harmless as plain ASCII but decoded to executable
<script>tags once a vulnerable browser auto-detected it as UTF-7 — bypassing filters that only checked for literal script-tag syntax in the raw input. This is a large part of why UTF-7 has a lingering reputation as a security liability rather than just an obsolete convenience encoding. - Modern browsers no longer auto-detect UTF-7, specifically because of this vulnerability class — but the historical episode is a commonly cited example in web security education of why encoding auto-detection (guessing charset without an explicit declaration) is inherently risky.
- Essentially unused for new systems. There's no ongoing technical reason to choose UTF-7 today — 8-bit-clean transport is the norm everywhere UTF-7 was historically needed, and UTF-8 covers the same representational goals more simply and without the security baggage.
- Different Base64 alphabet than standard Base64 — UTF-7's modified Base64 variant omits
=padding and handles line-wrapping differently, so generic Base64 tooling won't correctly decode UTF-7 content without UTF-7-aware logic specifically.
Fixing it
- Decoding legacy UTF-7 content: use a library with explicit UTF-7 support (Python's
codecsmodule includes autf-7codec) rather than attempting to adapt generic Base64 tooling, due to the alphabet and framing differences noted above. - If you encounter unexpected UTF-7 content in a modern system: treat it as a signal to investigate why — it's rare enough in 2026 that its presence is more likely a legacy artifact or a potential security-relevant anomaly than a deliberate modern design choice.
- Never rely on browser/client charset auto-detection for user-supplied content, partly because of the historical UTF-7 XSS pattern — always declare charset explicitly (
Content-Typeheader,<meta charset>) rather than letting a client guess.
Comparison
| Encoding | Key difference from UTF-7 |
|---|---|
| UTF-8 | 8-bit-clean, ASCII-compatible, no security history tied to charset auto-detection, and the modern default virtually everywhere |
| Quoted-Printable | A different MIME-era 7-bit-safe scheme, but designed for mostly-ASCII content with occasional special bytes rather than full Unicode text |
| Base64 | Shares some conceptual DNA (encoding non-ASCII data using a restricted character alphabet) but uses a different, simpler, and unrelated alphabet/framing scheme |
FAQ
Is UTF-7 still used anywhere?
Rarely, and mostly in legacy contexts — old archived emails, certain older telecom/messaging systems. It's not a recommended choice for any new system, and modern email infrastructure doesn't need it since 8-bit-clean transport (MIME with Base64/Quoted-Printable) has been standard for a long time.
Why is UTF-7 considered a security risk?
Specifically because some older browsers (notably certain Internet Explorer versions) would auto-detect content as UTF-7 without an explicit charset declaration, which attackers exploited to smuggle executable script content past filters that only checked for literal <script> syntax in the unencoded input. Modern browsers no longer do this kind of auto-detection.
How is UTF-7 different from Base64?
They both use a restricted, mostly-alphanumeric character set to represent arbitrary data, but they're structurally different — UTF-7 passes ASCII characters through unmodified and only Base64-encodes the non-ASCII portions (wrapped in +...- markers), while standard Base64 encodes the entire payload uniformly regardless of content.
Fun fact
UTF-7 was formally documented as an informational RFC (RFC 2152), never a full internet standard — a status that reflects its always-somewhat-provisional role as a stopgap for 7-bit-limited transport, rather than a first-class encoding intended for long-term general use the way UTF-8 was designed to be.