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.urlsplitto extract onlyhostnameandportfrom 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, orgit showoutput directly. - Before displaying output, check whether a value or a line containing it can still pass through.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes โ full credit and traffic to the original publisher.