All posts

Field guide

What to log and what to never log in your app

Logs feel private and internal, so it is easy to write anything to them. AI-built apps do exactly that, often dumping passwords, tokens, and full request bodies into the logs. But logs travel, and a secret in a log is a secret in a lot of places. Here is where to draw the line.

Last updated

Logging feels safe because logs feel private, so AI-built apps log generously, and frequently log the wrong things. The problem is that logs do not stay put. They get shipped to log services, read by people, retained for months, and occasionally exposed on their own. Anything sensitive you write to a log is now sitting in all of those places, outside whatever protections you put around the original. The fix is knowing what belongs in a log and what never does.

Never log these

  • Passwords, in any form, even to debug a login.
  • API keys, tokens, and session identifiers, which are exactly what an attacker wants.
  • Full card numbers and other regulated data.
  • Whole request or response bodies, which quietly carry all of the above.

The common AI pattern is logging a whole object or a raw error that happens to include the token:

// the risky pattern: logs the token on every request
console.log("request:", req.headers, req.body);
console.error("auth failed:", err);   // err may include the token/query

Want to see exactly what Prbl flags? Watch it scan a demo app, no repo or account needed.

See a live scan →

Log these instead

You can keep logs genuinely useful without exposing anyone. Log a timestamp, the route, a status, a user id rather than their email or token, and a random reference id you can match to an error report:

const ref = crypto.randomUUID();
console.error(ref, { route: "/api/orders", userId: user.id, status: 500 });
// return the ref to the client instead of the error detail

When you must log something derived from sensitive data, log a redacted or hashed version, enough to correlate, not enough to reuse. This is the same principle as the fix for sensitive data in logs and keeping secrets out of places they spread.

How to avoid accidental leaks

Do not log whole objects when they can carry secrets; log the specific fields you need. Use a logger that redacts known sensitive keys automatically. And look closely at your error handlers, since a caught error often contains the exact token or query that caused it, which is how secrets end up in logs without anyone deciding to put them there.

Frequently asked questions

Why is logging a secret dangerous if the logs are private?

Because logs travel further than you think. They get shipped to third-party log services, viewed by teammates and contractors, retained for months, and sometimes exposed by their own misconfigurations. A secret in a log is a copy of that secret in every one of those places, outside the protections you put around the original. Logs are not a safe place for anything you would not want widely seen.

What are the worst things to log?

Passwords, API keys and tokens, session identifiers, full credit card numbers, and complete request or response bodies that may contain any of those. AI tools often log a whole request object or an error that includes the token, which quietly writes credentials into your logs on every call. If a value would be dangerous in an attacker's hands, it does not belong in a log.

What should I log instead?

Log what helps you debug and audit without exposing anyone: a timestamp, the route, a status, a user id (not their email or token), and a random reference id you can tie an error report to. When you need to log something derived from sensitive data, log a redacted or hashed version, enough to correlate, not enough to reuse. The goal is useful logs that are safe if they leak.

How do I stop logging sensitive data by accident?

Do not log whole objects like the full request or a raw error when they can carry secrets; log the specific fields you need. Use a logger that supports redaction to strip known sensitive keys automatically. And review what your error handlers write, since a caught error often includes the very token or query that caused it. A little discipline at the log call prevents a lot of leaked data.

Check what your app exposes

Logging secrets is one way sensitive data escapes; shipping them to the browser is another. A scan flags secrets exposed in what your app serves, so you can close the obvious leaks first. Run a free scan and see what your app is exposing.

Prbl scans your live app or your codebase for exactly the kinds of issues above.

What to Log and What to Never Log in Your App: Prbl