Safeguard
Application Security•

CWE-150 Escape and Control Sequence Neutralization Failures

Terminal escape codes, mail tilde escapes and raw control characters can rewrite what users see. Here is how CWE-150 happens and how to fix it.

Safeguard Security Team
5 min read

CWE-150 describes a product that passes input to a downstream component without neutralizing escape, meta or control character sequences. The downstream component then treats those bytes as instructions instead of text.

The easiest place to see this is a terminal. A log line, a filename or a package description that contains ANSI escape codes can change colors, move the cursor, clear the screen and print a fake prompt. Developers who run command line tools, administrators who tail logs, and anyone using a CLI that echoes remote data are the people in the line of fire. The record also lists AI and ML systems among the affected platforms, which fits: model output and tool output often get printed straight to a console.

How it happens

A program takes a string from one place and writes it to another place that has its own control language. Nobody strips or encodes the control bytes in between.

# Vulnerable: remote data goes straight to the terminal
for entry in fetch_entries():
    print("Found file:", entry["name"])

If a name contains an ESC byte followed by cursor movement codes, the terminal obeys them. The output the human reads is no longer the output the program produced.

The observed examples show how wide this is. CVE-2024-27936 is a chain in a JavaScript application that removes ANSI escape sequences in a dialog asking permission for a particular file. That removal caused the wrong filename to be shown visually for approval, which also touches the misrepresentation weakness CWE-451. A cleanup step meant to be safe made the display lie.

Older cases come from mail programs. CVE-2002-0542 is a mail program that processes the special tilde escape sequence even when not running interactively. CVE-2000-0703 is a setuid program that does not filter escape sequences before calling a mail program. CVE-2002-0986 is a mail function that does not filter control characters from arguments, which allows message content to be modified.

Notice the repeated shape. An upstream component hands data to a downstream one, and the downstream one has a private escape language the upstream author never considered.

What an attacker gains

The record lists several integrity impacts: executing unauthorized code or commands, hiding activities, and unexpected state. It notes that ANSI escape codes can be used for low severity attacks such as changing the color of console output. They can also be used to move the cursor arbitrarily, clear the screen, and make fake prompts inside the interactive session.

That matters for two reasons. First, a fake prompt can trick an operator into typing something they would not otherwise type. Second, hiding activities is a real goal. If an attacker can overwrite or erase lines in a terminal, the person watching the output sees a cleaner story than what happened.

How to find it

The MITRE page rates automated static analysis as able to find some instances. Beyond that, check by hand.

  • Map every place program output reaches a terminal, a log viewer, a mail command or any other interpreter with escape syntax.
  • Feed test values that contain the ESC byte (0x1B), carriage returns, backspaces and other control characters through each input path, then inspect the rendered result.
  • Review any code that strips sequences with a regular expression. As the file permission example shows, partial stripping can change meaning.
  • Read your logging path. If logs are later viewed with a raw terminal tool, log injection and escape injection become the same problem.

How to fix it

The mitigation guidance in the record starts with an expectation: developers should anticipate that escape, meta and control characters will be injected, removed or manipulated in the input vectors of the product.

  1. Use an allowlist. Decide which characters a field may contain and reject or transform everything else. Printable text for a filename display is a much smaller set than all bytes.
  2. Neutralize at the output boundary. When data goes to a terminal, replace control characters with a visible placeholder instead of passing them through.
import re

CONTROL = re.compile(r"[\x00-\x08\x0b-\x1f\x7f]")

def safe_for_terminal(text: str) -> str:
    return CONTROL.sub("?", text)

for entry in fetch_entries():
    print("Found file:", safe_for_terminal(entry["name"]))
  1. Prefer replacing over silently deleting. The CVE-2024-27936 chain shows that removing bytes can alter what the user thinks they are approving. A visible marker keeps the display honest.
  2. Do not call mail or similar helper programs with attacker influenced text as arguments or input without disabling their escape processing. Run them in non-interactive mode and pass data as data.
  3. Validate consistently across all properties: length, type, range, syntax and business rules. Reject input that does not conform instead of trying to repair it.

Dependencies that print for you

Many terminal problems come from libraries that format and print remote data, such as package managers, log formatters and test runners. You may not own the printing code. The free in-browser dependency scan takes a manifest or lockfile of up to 100 dependencies with no login, and the file stays on your machine. Reachability analysis then tells you whether your code actually calls the affected function, so you can sort real exposure from noise.

Quick check

Is color manipulation the worst an escape code can do?

No. The record notes cursor movement, screen clearing and fake prompts inside an interactive session. Those can mislead an operator and hide activity.

Why can stripping escape sequences make things worse?

Because removal changes the visible text. In CVE-2024-27936, removal contributed to the wrong filename being shown in a permission dialog. Safer handling replaces control bytes with a visible marker or rejects the input.

Does this only affect terminals?

No. The observed examples include mail programs that interpret special escape sequences. Any downstream component with its own escape syntax is a candidate.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.