Skip to content
1Claw Academy
Curriculum/Foundations2 minBeginner · Lesson 10 of 13

Lab: delete a secret and watch it survive

Lab

Commit a .env, remove it, add a .gitignore, then read the secret straight back out of the repository.

The previous lesson told you to delete the .env after importing it. This lab is why that instruction has a second half, and why the second half is the one people skip.

  1. 1

    Make a throwaway repository and commit a .env, exactly as it happens by accident.

    bash
    mkdir -p /tmp/gitlab && cd /tmp/gitlab
    git init -q . && git config user.email you@example.com && git config user.name You
    printf 'STRIPE_KEY=sk-live-9f2a-LEAKED\n' > .env
    git add .env && git commit -qm "add config"
  2. 2

    Notice the mistake and do the obvious cleanup: remove the file, add a .gitignore, commit.

    bash
    git rm -q .env
    printf '.env\n' > .gitignore
    git add .gitignore && git commit -qm "remove secret, add gitignore"
    ls -a
  3. 3

    The working tree is clean. The secret is not gone.

    bash
    git log -p --all | grep -o 'sk-live[^ ]*'
  4. 4

    Read it directly out of the earlier commit, which is what anyone who clones the repository can do.

    bash
    git show HEAD~1:.env
    # -> STRIPE_KEY=sk-live-9f2a-LEAKED
  5. 5

    Clean up.

    bash
    cd /tmp && rm -rf gitlab

Deleting a file removes it from the current commit and from nothing else. Git is designed to preserve history, and it did its job perfectly.

  • Anyone who has ever cloned or forked the repository already has the secret, and nothing you do to your copy reaches theirs.
  • Rewriting history with filter-repo or BFG changes the object graph and does not un-distribute what was pushed, and it does not touch a fork.
  • On a hosted platform the old objects may remain reachable by commit SHA long after the branch is rewritten.
Watch out

The only response that actually works is rotation. Treat a committed secret as burned from the moment it is pushed, rotate it, and clean the history afterwards as tidying rather than as the fix.

Tip

Add .env to .gitignore in your project template rather than after the first mistake. A gitignore added in commit two protects nothing that happened in commit one.

This is the fourth way a secret escapes that this course has shown you and none of them involved an attacker doing anything clever: a build log, a process table, a plaintext file, and now version control that is faithfully doing what it was built to do.

Check your understanding

3 questions
1

You deleted the .env and committed. Why is the secret still exposed?

2

What is the only response that reliably works?

3

When should .env go into .gitignore?