Log injection: forging entries in your own logs

Logs are evidence. When request data is written to them unescaped, a line break in that data lets the caller add entries of their own.

Example

Vulnerable
console.log("Login failed for user:", req.body.userName);
// userName = "alice\nINFO Login succeeded for user: admin"
Fixed
const clean = String(req.body.userName).replace(/[\r\n]/g, "");
logger.warn({ event: "login_failed", user: clean });
// or a structured logger that writes values as JSON fields

How it happens

A username of alice followed by a newline and INFO Login succeeded for user: admin produces two log lines, the second written by the attacker. Forged entries can cover tracks, frame another user or confuse alerting rules. Logs shown in a web dashboard add a second risk: HTML in the entry can become XSS in the viewer.

How to fix it

Keep each value inside its own entry.

  • Strip or encode \r and \n from user data before logging
  • Prefer a structured logger (pino, winston with JSON) that writes values as fields
  • Escape log content when displaying it in HTML
  • Avoid logging secrets and full request bodies at all

How RepoVerse finds it

  • LowRequest input written to the log unescaped

    A value with line breaks forges extra log entries — a fake "login succeeded" line, or noise that hides the real attack from whoever reads the logs later.

    data flow · CWE-117

Questions

Is log injection a serious vulnerability?
It is usually rated low on its own, but it undermines the logs you rely on to investigate every other incident, and can chain into XSS in log viewers.
How does RepoVerse find log injection?
It traces request input to console and logger calls. Signature-verified webhook payloads are not treated as attacker input.

Related

Updated 2026-10-11