Dev.to AI ๐Ÿค– Ai ๐Ÿ‘ 0 ๐Ÿ“– 4 min read

Why grep and URL Splitting Exposed Secrets 3 Times

๐Ÿ“ Originally published (in Japanese) at forge.workstyle.tech. TL;DR I was investigating settings across multiple AI sessions and intended to keep secrets out of the output. URL splitting and grep filtering still left p

๐Ÿ“ Originally published (in Japanese) at forge.workstyle.tech.

TL;DR I was investigating settings across multiple AI sessions and intended to keep secrets out of the output. URL splitting and grep filtering still left paths for passwords to reach the screen. I now check whether values can pass through before displaying output.

The takeaway

Splitting URLs or filtering lines with grep cannot eliminate every path by which secrets may remain in the output; database, Redis, and object storage passwords were displayed. I decided to redact anything that might contain secrets with Python, then review the output before publishing it to check for any remaining paths through which values could leak.

Why Splitting a URL Also Displayed the Database Password

In the initial output, I meant to extract only the host from a connection URL, but I ended up displaying the database administratorโ€™s password too.

To extract just the host from the connection URL, I used this split:

v.split('://')[-1].split('/')[0]

The result kept the entire user:password@host portion, so the database administratorโ€™s password was displayed too.

I wanted to extract only the host. But I hadnโ€™t checked whether the result of splitting on delimiters included credentials. Even if the goal was โ€œhost only,โ€ the code didnโ€™t guarantee that.

This output was one reason to recreate the values. I recreated the database and Redis values during the same night, from 00:24 to 00:54.

Why Did grep -A4 Display the Redis Password?

The second time, while inspecting a configuration file, I used grep -A4 to show the four lines after the matching line, and it displayed the Redis password.

The plaintext Redis password on the adjacent line appeared in the output.

The records donโ€™t show whether this happened before or after the rebuild. I canโ€™t fill in the sequence. What remains is the result: when a secret is on a neighboring line, a search that displays surrounding lines can expose it too.

Why grep -v "value:" Still Revealed the Root Password

On the third attempt, at 00:4x, I ran grep -v "value:" intending to exclude lines containing values. The object storage root password still appeared.

The command to configure an alias for the object storage included the password as an argument. Because that line didnโ€™t contain value:, it remained in the output, exposing the root password.

All three values had already been stored in plain text in the repositoryโ€™s history. I rotated the storage root password at 01:02. Even though I had transformed the output to prevent exposure, there was still a path for the values under investigation to pass through.

Why od -c | sed Still Failed to Redact the Token

On October 10, I once again tried to hide a token with od -c | sed, but its prefix appeared in the conversation log.

od inserts spaces between characters, so the sed replacement didnโ€™t match. As a result, the tokenโ€™s prefix appeared in the conversation log.

I decided to ask for the token to be recreated. However, the record doesnโ€™t say whether it was actually recreated. What we can confirm is only that I decided to request it.

The three incidents that happened three days later looked like different approaches, but followed the same pattern. After a step that exposed a value, they split strings or filtered out lines. They didnโ€™t check whether the value remained in the processed result before outputting it.

How to Check for Secrets Before Outputting Results

From here on, I decided to redact anything that might contain secrets with Python before outputting it.

I donโ€™t output the results of grep -A, grep -B, grep -C, cat, sed -n, git diff, or git show as-is.

When checking a URL, I use urllib.parse.urlsplit to extract only the hostname and port. When I need to compare values without revealing them, I use the beginning of their SHA-256 hashes. I also prepared a tool for this.

Using a tool doesnโ€™t make the output safe automatically. Before outputting anything, I reread it to check whether thereโ€™s still a path for values to leak through.

It wasnโ€™t enough to โ€œwrite a command that hides secrets.โ€ Each operationโ€”splitting URLs, showing surrounding lines, and excluding lines by stringโ€”left a path for values to remain in the output.

Whether youโ€™re investigating production settings or asking an AI agent to do the investigation, you can pause before reading the output. Check not the name of the redaction process, but whether thereโ€™s any path for values to make it into the output.

Key takeaways

  • Use urllib.parse.urlsplit to extract only hostname and port from a URL.
  • Redact output that may contain secrets with Python before displaying it.
  • Do not display grep -A, grep -B, grep -C, cat, sed -n, git diff, or git show output directly.
  • Before displaying output, check whether a value or a line containing it can still pass through.
๐Ÿ“ฐ Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes โ€” full credit and traffic to the original publisher.