Sensitive Data Logging

When your debugging tool becomes a goldmine for hackers.

The idea

Applications generate logs to help developers debug issues. However, if those logs contain Personally Identifiable Information (PII) like passwords, credit card numbers, or session tokens, the logging system itself becomes a massive security vulnerability. Logs are usually stored in plain text, kept for months, and accessible to many employees who wouldn't normally have database access.

Step 1: A user submits a login request. The server parses the JSON.

How it works (Log Scrubbing)

Never dump raw request payloads or error tracebacks into logs without sanitization. You should configure your logging library to automatically scrub keys like `password`, `token`, or `card_number` before the log string is ever created.

# VULNERABLE: Dumping the raw request
@app.route("/login", methods=["POST"])
def login():
    # DANGER: The user's plaintext password is now in Datadog/Splunk forever.
    logger.info(f"Incoming login request: {request.json}") 

# SECURE: Explicit Logging
@app.route("/login", methods=["POST"])
def login():
    # Only log exactly what you need.
    logger.info(f"Login attempt for user: {request.json.get('username')}")

Watch out for

Worked example

In 2018, Twitter (now X) announced a bug where they were storing passwords in plain text in an internal log. Before completing the hashing process, the code was writing the raw password to a debug log. They had to ask all 330 million users to change their passwords, purely because of a single overzealous `console.log()`.

Check yourself

Why is it a bad idea to send an API Key in the URL, like `GET /api/data?api_key=secret_123`?

While URLs do have length limits, API keys are rarely that long. That's not the security concern.
Exactly! Every hop along the network, and the final server itself, will naturally log the full URL, exposing the secret. Secrets belong in headers.