DEV Community

Cover image for Final Tale: Part 3 - The Gateways We Left Open
Peter Davis
Peter Davis

Posted on

1 1 1 1 1

Final Tale: Part 3 - The Gateways We Left Open

Part 3 of 3 in Git Tales Series
Enter fullscreen mode Exit fullscreen mode

"Some files vanish from sight, but not from memory. Git remembers. So do attackers."

We’ve journeyed deep into the underbelly of modern software development where secrets hide in plain sight, tucked between commits and CI scripts, waiting to be exhumed. In Part 1, we met the careless developer. In Part 2, we followed the breadcrumbs into service accounts, dangling credentials, and quiet privilege escalation in the cloud.

Now, this is the final part of the Git Tales trilogy — and unlike the previous tales, this one breaks apart into three standalone compromises, each unearthed through separate hunts, reported via three different bug bounty programs, and rewarded with high to critical payouts.

Each started differently. Each felt like an accident — a digital whisper. But each time, that whisper led to something massive.

🧨 [ CVE-GIT-001 ]: The Script That Wouldn’t Die

It began like any other passive recon session — checking out a newly public GitHub repository tied to a mid-sized tech company. Nothing looked special on the surface: some README files, a few basic Go services, and tests.

But something odd caught my attention in the commit history, a file named test.sh had been committed and then deleted. I’d seen this pattern before 😅. And 9 out of 10 times, it's harmless. But that one time? It changes everything.

I pulled the repo and dug deeper. A single commit. Then gone.
But Git’s memory is long.

git checkout <commit-hash>^ -- test.sh

Enter fullscreen mode Exit fullscreen mode

And there it was.

A simple bash script, or so it seemed — containing an HTTP call with a GitHub token hardcoded in plain sight:

#!/bin/bash
curl -H "Authorization: token ghp_abcd1234EXAMPLETOKEN" https://api.github.com/orgs/example-org/repos
Enter fullscreen mode Exit fullscreen mode

I stared at the token. I validated it with trembling fingers 🥲. It wasn’t expired.

curl -H "Authorization: token ghp_abcd1234EXAMPLETOKEN" https://api.github.com/user
Enter fullscreen mode Exit fullscreen mode

200 OK!!! 😅. I was in.

Impact

  • Access to 20+ private repos
  • Read/write permissions across the org
  • Internal CI/CD workflows, API keys, infra configs
  • GitHub Actions secrets exposed

I submitted a report through their program, and within hours, triage confirmed its validity. A few days later, the bounty landed 🐞.

🐳 [ CVE-CONTAINER-666 ]: Ghost in the Registry

I wasn’t even looking for containers. Just passively scanning Git objects in a public repo of a private bug bounty program when I found a file named nginx-test-secret.yaml

It was gone from the live branch. Deleted months ago. But as always, Git’s memory outlived the author’s intention.

bye

The file contained base64-encoded ACR credentials. My pulse picked up. Was this real?

ACR Creds

I decoded it. Logged in.

docker login myregistry.azurecr.io -u acr-user -p s3cr3tP@ss

docker login

Success. The registry door opened.

What It Unlocked

  • 80+ private container images
  • Secrets in ENV layers (.env, secrets.py)
  • Pre-production builds, old tokens, debug configs
  • Internal microservices

One image even had Slack bot credentials embedded in its CMD layer. The registry was unscoped. There was no IP filtering. No token rotation. This was a supply chain bomb waiting to go off.

🧱 [ CVE-FUZZ-777 ]: The Git Leak That Bit Back

Sometimes, the real treasures aren’t in public repos or code. They’re in the infrastructure someone forgot existed. They call it "Shadow IT???" 🤔.

While targeting a company’s legacy subdomains, I started a fuzzing job out of curiosity — just to rule out low-hanging fruit. After hours of generic 403s and 404s, I hit on a strange path:

https://old-ci.example.com/test/internal/.git
Enter fullscreen mode Exit fullscreen mode

I download the .git folder to my VPS for analysis and testing.

wget -r -np -nH --cut-dirs=1 -R "index.html*" https://old-ci.example.com/test/internal/.git
Enter fullscreen mode Exit fullscreen mode

Download git

I checked the .git/config file cause I know based on previous experience some devs set creds here 🤫. A full config file, raw and alive with BitBucket credentials present.

[remote "origin"]
  url = https://devuser:bb_app_password@bitbucket.org/orgname/infra.git
Enter fullscreen mode Exit fullscreen mode

access

I paused. Was it real? One command later git clone https://devuser:bb_app_password@bitbucket.org/orgname/infra.git

Boom🤯🤯🤯. Repo cloned. Zero MFA. No IP lock. No alerts.

And this was just the start. The Bitbucket account had access to multiple workspaces (3). In the following hours, performed some critical tests to check the scope of the credentials.

stage 2

Tests Performed

List All Repositories via Bitbucket API

repos

List Workspaces the user belongs to

workspaces

Impact

  • Access to 60+ internal repos.
  • CI/CD secrets, API keys, Terraform configs.
  • Slack webhooks, pipeline tokens
  • Exposure across 3 different Bitbucket workspaces

This was a critical security hole via infrastructure drift — the kind of bug you only catch by digging where no one else looks anymore.

🧠 Lessons from the Fallout

This breach wasn’t theoretical. Every piece of it mirrors real-world incidents that have happened — sometimes quietly, sometimes splashed across news headlines.

special

🔐 What should have been done?

  • Use least-privilege tokens. Never commit a token with org-wide access. Or just never commit any secrets...
  • Secrets detection in CI using tools like Gitleaks, or GitHub's native secret scanning.
  • Use managed identities - Especially for container registries and pipelines. No passwords in YAML.
  • App passwords ≠ secure APIs. Especially in Bitbucket, where app passwords are commonly over-scoped and under-rotated.
  • Monitor audit logs. Both GitHub and Bitbucket offer event logs — but too few organizations actively monitor them.

🔚 The Tale Ends, But the Threat Lingers

The Git Tale wasn’t about zero days or advanced persistent threats. It was about something more dangerous, misplaced trust and developer convenience turned blind spot.

As we close this series, remember:

"Every secret you commit lives forever — unless you treat it like the threat it is."

Your containers aren’t safe just because they’re in a private registry. Your GitHub isn’t secure just because it’s behind SSO. Your Bitbucket isn't safe because it’s split into "separate" workspaces.

Attackers don’t care about your silos. They care about your secrets — and Git will gladly index them for the world to see.

👣 What’s Next?

That’s the end of the Git Tales Series — but just the beginning of a broader journey.

end-it

Stay tuned for my next series: “*A bug represents something bigger *” — where we dive into the mind of a hacker or bug bounty hunter.

Until then, guard your Git, rotate your keys, and never trust a silent repo.

Dynatrace image

Frictionless debugging for developers

Debugging in production doesn't have to be a nightmare.

Dynatrace reimagines the developer experience with runtime debugging, native OpenTelemetry support, and IDE integration allowing developers to stay in the flow and focus on building instead of fixing.

Learn more

Top comments (0)

Tiger Data image

🐯 🚀 Timescale is now TigerData: Building the Modern PostgreSQL for the Analytical and Agentic Era

We’ve quietly evolved from a time-series database into the modern PostgreSQL for today’s and tomorrow’s computing, built for performance, scale, and the agentic future.

So we’re changing our name: from Timescale to TigerData. Not to change who we are, but to reflect who we’ve become. TigerData is bold, fast, and built to power the next era of software.

Read more

👋 Kindness is contagious

Explore this insightful write-up, celebrated by our thriving DEV Community. Developers everywhere are invited to contribute and elevate our shared expertise.

A simple "thank you" can brighten someone’s day—leave your appreciation in the comments!

On DEV, knowledge-sharing fuels our progress and strengthens our community ties. Found this useful? A quick thank you to the author makes all the difference.

Okay