top of page
Search

Secret Hygiene Part 1: Stop Pushing Plaintext

Writer: Martin Ladecký
Martin Ladecký
3 days ago
3 min read

We put a lot of effort into building zero-trust networks, creating Software Bills of Materials (SBOMs), and securing our production clusters. But industry data shows that most breaches still happen for one main reason: compromised credentials.

When delivery pressure increases, especially with AI coding assistants encouraging speed, developers regularly prioritise convenience over security. As a result, secrets can end up in local build configs, get committed to repositories, and remain in commit histories. Research suggests AI makes it even worse. Doubling the amount of secrets in plain text (source).

This guide explains how common developer tools can leak access keys, why typical cleanup methods fail, and how to secure your local development setup in just five minutes.


The Maven settings.xml Hazard

When using internal enterprise mirrors like Nexus or Artifactory, you need authenticated access. Most developers set this up once and forget about it, often putting active domain accounts or privileged user credentials in ~/.m2/settings.xml as plain text:

<server>
    <id>internal-repository</id>
    <username>martin.ladecky</username>
    <password>CorporateDomainPass123!</password>
</server>

Why Plaintext Configuration Fails

  1. Ad-Hoc Troubleshooting Leaks: If an engineer runs into dependency resolution problems, they might ask a coworker to share their settings.xml file. Trying to remove passwords quickly can lead to mistakes, sometimes leaving personal credentials in the shared file.

  2. Build Agent Inspection: Teams often reuse local settings files in automated build workers.

  3. Configuration Introspection: Depending on your Maven version, these credentials can be easily seen. Running simple inspection commands can show credentials in plain text in the console logs:

mvn help:effective-settings

In older or unpatched environments, running Maven with debug flags (-X) can print authorisation headers directly to the standard output.

┌────────────────────────────────────────────────────────────────────────┐
│                     THE 5-MINUTE MAVEN ENCRYPTION                      │
├───────────────────┬────────────────────────────────────────────────────┤
│ Step 1: Master Key│ mvn --encrypt-master-password <master-pass>        │
│ Step 2: Key Store │ Store hash inside ~/.m2/settings-security.xml      │
│ Step 3: Password  │ mvn --encrypt-password <server-password>           │
│ Step 4: Storage   │ Store encrypted password token in settings.xml     │
└───────────────────┴────────────────────────────────────────────────────┘

After setup, Maven handles authentication tokens automatically and does not store raw credentials on disk.


Git History is Append-Only

A common mistake is adding an active secret or local config file to a working branch, committing it, and pushing it upstream.

After noticing the mistake, an engineer might run:

git rm secret.properties
git commit -m "Remove sensitive properties"
git push

Even though the active tree looks clean, the secret remains in the commit history.

Since Git keeps immutable snapshots, anyone with read access to the repository can look through past revisions on all local and remote branches:

git log --all -S "password="

Static analysis tools look for tokens like secret=, api_key=, or credential= in this way across all parts of the repository.

COMMIT LOG EXPOSURE
commit c3a891f... (HEAD -> main) Remove sensitive properties
commit b71402e... (EXPOSED)      Add internal service connector (secret embedded)

Trying to rewrite commit history with tools like git filter-repo or force-pushes can cause merge conflicts, break your teammates' branches, and won't work if someone else has already cloned the old revision.


The Operational Rule of Leaked Secrets

Once a secret leaves your own workstation:

If a credential is exposed in any shared pipeline, commit log, or artifact, there is only one safe solution: REVOKE THE CREDENTIAL IMMEDIATELY.

Don't rely on scrubbing tools or think that internal visibility settings will prevent exposure. Always treat exposed credentials as compromised.


Moving to Runtime Memory

Protecting static files on disk and keeping secrets out of repository logs removes the easiest entry point for attackers. However, once your application is running, those credentials still need to be stored somewhere.

In Part 2, we'll look at what happens at runtime: how database logins and internal API keys can stay in JVM Heap Dumps, and how unprivileged processes may pull active secrets from Java memory.


Feel free to add a comment or contact me for more in-depth details. As always, do not try it with your corporate account/environment without approval from your boss. This is a really dangerous setup.


 
 
 

Comments


©2021 by Martin Ladecký

bottom of page