Build1 publisher2 min readPublished
A log dashboard on default credentials hands over every plaintext password
In a deliberately vulnerable training app, a debug statement writes every login password to a cleartext log file, and a monitoring console left on root and admin lets anyone read that file through a browser.
The Engineer · Build desk

What happened
- A walkthrough reads every user's plaintext password straight from a log viewer, without ever querying the application's database.
- The console opens with the default credentials root and admin, on a page titled SIEM Console.
- A single login attempt drops a log line reading password=iloveduck beside the flag OSS{pl41nt3xt_p4ssw0rd_1n_l0gs}.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint Encrypting or hashing the password store fixes nothing here: the debug line captures the plaintext before any hashing runs, so the database was never the weak point.
- exposure The console sits on the app's own port and takes root:admin, so the log file becomes an effectively unauthenticated read of every password submitted.
- capability Redacting fields at the logging library keeps the password out of output even when the message string contains it, which reviewing the code alone will miss.
The line doing the damage is a `logger.warn` call in the login route. On every POST to `/api/auth/login` it writes the email, the submitted password and the challenge flag straight into the log message [3]. A structured logger does not save you here; as the writeup notes, "A structured logger doesn't prevent developers from embedding credentials in the message string itself." [14] The entry lands in `logs/app.log` in cleartext [4]. So the password is captured before anything hashes it, and whatever the database does at rest never comes into it [2].
Finding the reader is a directory-enumeration job. The login response is identical whether the credentials are right or wrong [9], so the front door tells you nothing. Point gobuster at the app and `/monitoring` shows up; a second pass turns up `/monitoring/siem`, which is linked nowhere in the app [5]. The page is a login form titled "SIEM Console." It opens to `root` and `admin` [6].
The dashboard stays empty until someone logs in on the main app. Fire one attempt and the captured line appears in the log table: `password=iloveduck` next to the flag `OSS{pl41nt3xt_p4ssw0rd_1n_l0gs}` [8]. The table shows all captured output, so anyone with the console can read it back [7].
The writeup counts four things that had to go wrong and files them as CWE-532, CWE-312, CWE-200 and CWE-798 [10]. None of the four is a cryptographic weakness [17]. Two cover logging what should never be logged and storing it in the clear; two cover a dashboard that is trivial to find and takes a password anyone would try [17]. Cryptography is one of the categories in this training app's 36 challenges [15][1]; this chain is an observability-hygiene failure instead.
The fixes are unglamorous. Redact sensitive fields at the logging layer so a password cannot reach output even when a developer forgets to strip it [11]. Treat any log that can identify a user like the user table: access controls, encryption at rest, retention [12]. And give internal tools real credentials. As the writeup puts it, "Default passwords on an internal dashboard are fine until the dashboard is reachable from the internet." [13]
What to watch
- Whether the same debug-line-plus-default-dashboard pattern turns up in a real deployment, which would move it out of the training lab.
- Whether the OopsSec project publishes a fixed branch showing the redacted logger config and SSO-backed console.
- Whether monitoring consoles keep shipping on default credentials once they are reachable on production ports.