Skip to content

Console logger should sanitize control characters in log messages #128727

@halter73

Description

@halter73

Summary

The built-in console logger (Microsoft.Extensions.Logging.Console) does not escape
or strip control characters (e.g., ANSI escape sequences, carriage returns, newlines,
backspaces) that may be present in logged values. This means that untrusted data flowing
through ILogger.Log(...) can emit arbitrary terminal control sequences to the console.

Problem

When applications log user-controlled input — such as HTTP request headers, query
strings, or form values — any embedded control characters are written verbatim to the
terminal. This can lead to:

  • Terminal manipulation — an attacker-controlled string can rewrite previously
    displayed lines, hide output, or alter colors to mislead an operator reading logs.
  • Confusing log output — control characters can break log parsing tools, corrupt
    structured log viewers, or cause unexpected behavior in CI/CD pipelines that consume
    stdout.

This affects all console formatters (Simple, Systemd, Json) that write to
System.Console / stdout without sanitizing the message or state values.

Reproduction

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", (HttpContext ctx) =>
{
    var userInput = ctx.Request.Query["name"].ToString();
    app.Logger.LogInformation("Hello {Name}", userInput);
    return "OK";
});

app.Run();

Request: GET /?name=%1b%5b31mRED%20TEXT%1b%5b0m

The console output renders "RED TEXT" in red (or other terminal-dependent behavior)
rather than showing the escaped representation.

Proposed Solution

The console formatters should sanitize messages before writing to the output stream.
Control characters (Unicode categories Cc/Cf, excluding common whitespace like \n and
\t when they are part of the formatter's own layout) should be stripped or replaced
with an escape representation (e.g., \x1B or ).

This would be a defense-in-depth improvement — applications should already validate
input, but the logging infrastructure should not blindly pass control sequences to the
terminal.

Considerations

  • This is a behavioral change in the formatter output, so it may warrant an opt-out
    switch (e.g., ConsoleFormatterOptions.SanitizeControlCharacters = true by default).
  • The JsonConsoleFormatter already JSON-encodes strings, but should still sanitize
    values written outside of JSON payloads (e.g., timestamp prefixes from state values).
  • HttpLoggingMiddleware in ASP.NET Core is one specific caller that logs request/
    response data, but the fix belongs in the logging infrastructure itself so all
    consumers benefit.

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions