<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Peter Davis</title>
    <description>The latest articles on Forem by Peter Davis (@davisbug).</description>
    <link>https://forem.com/davisbug</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F916225%2Ffe9583e1-b69c-4b5a-a0ba-48cc9cc7275a.png</url>
      <title>Forem: Peter Davis</title>
      <link>https://forem.com/davisbug</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/davisbug"/>
    <language>en</language>
    <item>
      <title>Final Tale: Part 3 - The Gateways We Left Open</title>
      <dc:creator>Peter Davis</dc:creator>
      <pubDate>Fri, 30 May 2025 11:48:34 +0000</pubDate>
      <link>https://forem.com/davisbug/final-tale-part-3-the-gateways-we-left-open-2o3d</link>
      <guid>https://forem.com/davisbug/final-tale-part-3-the-gateways-we-left-open-2o3d</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Part&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;Git&lt;/span&gt; &lt;span class="nx"&gt;Tales&lt;/span&gt; &lt;span class="nx"&gt;Series&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;"Some files vanish from sight, but not from memory. Git remembers. So do attackers." &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;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 &lt;a href="https://dev.to/davisbug/git-tales-secrets-in-the-shadows-2n8b"&gt;Part 1&lt;/a&gt;, we met the careless developer. In &lt;a href="https://dev.to/davisbug/git-tales-part-2-demons-in-the-cloud-2ii9"&gt;Part 2&lt;/a&gt;, we followed the breadcrumbs into service accounts, dangling credentials, and quiet privilege escalation in the cloud.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Each started differently. Each felt like an accident — a digital whisper. But each time, that whisper led to something massive.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Script That Wouldn’t Die
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;But something odd caught my attention in the commit history, a file named &lt;code&gt;test.sh&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;I pulled the repo and dug deeper. A single commit. Then gone.&lt;br&gt;
But Git’s memory is long.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;checkout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;^&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sh&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there it was.&lt;/p&gt;

&lt;p&gt;A simple bash script, or so it seemed — containing an HTTP call with a GitHub token hardcoded in plain sight:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;span class="nx"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization: token ghp_abcd1234EXAMPLETOKEN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//api.github.com/orgs/example-org/repos&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I stared at the token. I validated it with trembling fingers 🥲. It wasn’t expired.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization: token ghp_abcd1234EXAMPLETOKEN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//api.github.com/user&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;200 OK!!! 😅. I was in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Impact
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Access to 20+ private repos&lt;/li&gt;
&lt;li&gt;Read/write permissions across the org&lt;/li&gt;
&lt;li&gt;Internal CI/CD workflows, API keys, infra configs&lt;/li&gt;
&lt;li&gt;GitHub Actions secrets exposed&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  Ghost in the Registry
&lt;/h2&gt;

&lt;p&gt;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 &lt;code&gt;nginx-test-secret.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It was gone from the live branch. Deleted months ago. But as always, Git’s memory outlived the author’s intention.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahj9cyke4w2fbl6z84js.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahj9cyke4w2fbl6z84js.gif" alt="bye" width="498" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The file contained base64-encoded ACR credentials. My pulse picked up. Was this real?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fteanzvga2c0oz4xipl83.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fteanzvga2c0oz4xipl83.png" alt="ACR Creds" width="800" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I decoded it. Logged in. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker login myregistry.azurecr.io -u acr-user -p s3cr3tP@ss&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faxomerjw0pitlgwqtogz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faxomerjw0pitlgwqtogz.png" alt="docker login" width="800" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Success. The registry door opened.&lt;/p&gt;

&lt;h3&gt;
  
  
  What It Unlocked
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;80+ private container images&lt;/li&gt;
&lt;li&gt;Secrets in ENV layers (.env, secrets.py)&lt;/li&gt;
&lt;li&gt;Pre-production builds, old tokens, debug configs&lt;/li&gt;
&lt;li&gt;Internal microservices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Git Leak That Bit Back
&lt;/h2&gt;

&lt;p&gt;Sometimes, the real treasures aren’t in public repos or code. They’re in the &lt;strong&gt;infrastructure&lt;/strong&gt; someone forgot existed. They call it "Shadow IT???" 🤔.&lt;/p&gt;

&lt;p&gt;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 &lt;strong&gt;403s&lt;/strong&gt; and &lt;strong&gt;404s&lt;/strong&gt;, I hit on a strange path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//old-ci.example.com/test/internal/.git&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I download the .git folder to my VPS for analysis and testing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;wget&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;np&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;nH&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;cut&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;dirs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index.html*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//old-ci.example.com/test/internal/.git&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvzk1bbp8kqsm72ic1899.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvzk1bbp8kqsm72ic1899.png" alt="Download git" width="800" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I checked the &lt;code&gt;.git/config&lt;/code&gt; file cause I know based on previous experience some devs set creds here 🤫.   A full &lt;em&gt;&lt;strong&gt;config&lt;/strong&gt;&lt;/em&gt; file, raw and alive with BitBucket credentials present.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;remote&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;origin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//devuser:bb_app_password@bitbucket.org/orgname/infra.git&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyxofbhyzotqu069j74by.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyxofbhyzotqu069j74by.png" alt="access" width="800" height="183"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I paused. Was it real? One command later &lt;code&gt;git clone https://devuser:bb_app_password@bitbucket.org/orgname/infra.git&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Boom🤯🤯🤯. Repo cloned. Zero MFA. No IP lock. No alerts. &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8bhxxmxr052qoonx033l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8bhxxmxr052qoonx033l.gif" alt="stage 2" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tests Performed
&lt;/h3&gt;

&lt;h4&gt;
  
  
  List All Repositories via Bitbucket API
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqm2id22oiw50jrky3uwc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqm2id22oiw50jrky3uwc.png" alt="repos" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  List Workspaces the user belongs to
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv9s8lzs8iyi3s6alzo17.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv9s8lzs8iyi3s6alzo17.png" alt="workspaces" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Impact
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Access to 60+ internal repos.&lt;/li&gt;
&lt;li&gt;CI/CD secrets, API keys, Terraform configs.&lt;/li&gt;
&lt;li&gt;Slack webhooks, pipeline tokens&lt;/li&gt;
&lt;li&gt;Exposure across 3 different Bitbucket workspaces&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  Lessons from the Fallout
&lt;/h2&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folh7la99luvdg3elm774.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folh7la99luvdg3elm774.gif" alt="special" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What should have been done?
&lt;/h3&gt;

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

&lt;h2&gt;
  
  
  The Tale Ends, But the Threat Lingers
&lt;/h2&gt;

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

&lt;p&gt;As we close this series, remember:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Every secret you commit lives forever — unless you treat it like the threat it is."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Attackers don’t care about your silos. They care about your secrets — and Git will gladly index them for the world to see.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;That’s the end of the Git Tales Series — but just the beginning of a broader journey.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foixcngjoflz0h4qwwdaa.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foixcngjoflz0h4qwwdaa.gif" alt="end-it" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Until then, guard your Git, rotate your keys, and never trust a silent repo.&lt;/p&gt;

</description>
      <category>infosec</category>
      <category>git</category>
      <category>bitbucket</category>
      <category>bugbounty</category>
    </item>
    <item>
      <title>Git Tales: Part 2 - Demons in the Cloud</title>
      <dc:creator>Peter Davis</dc:creator>
      <pubDate>Fri, 09 May 2025 10:05:39 +0000</pubDate>
      <link>https://forem.com/davisbug/git-tales-part-2-demons-in-the-cloud-2ii9</link>
      <guid>https://forem.com/davisbug/git-tales-part-2-demons-in-the-cloud-2ii9</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Part&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;Git&lt;/span&gt; &lt;span class="nx"&gt;Tales&lt;/span&gt; &lt;span class="nx"&gt;Series&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/davisbug/git-tales-secrets-in-the-shadows-2n8b"&gt;previous part&lt;/a&gt; of this series, we explored the haunting reality of sensitive secrets buried within Git repositories lurking quietly, waiting to be discovered. This time, we dig deeper into the darkness. This is the tale of &lt;strong&gt;cloud credentials&lt;/strong&gt;: specifically, &lt;strong&gt;AWS access keys&lt;/strong&gt; and &lt;strong&gt;GCP service account keys&lt;/strong&gt; — the demons that, when found, can open portals into your cloud infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F34unha0pehsiyhgqzimx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F34unha0pehsiyhgqzimx.gif" alt="Let-go" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not fiction. These were real credentials found in public GitHub repositories. The implications? Full access to critical cloud resources, with barely any barriers.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Credentials Purpose
&lt;/h3&gt;

&lt;h4&gt;
  
  
  AWS Access Keys - CLI/SDKs
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft4zpmcvguxep1g46fiqu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft4zpmcvguxep1g46fiqu.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  What are they?
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/sdkref/latest/guide/feature-static-credentials.html" rel="noopener noreferrer"&gt;AWS Access Keys&lt;/a&gt; are used to programmatically interact with AWS resources via the AWS CLI or SDKs.&lt;/p&gt;

&lt;h5&gt;
  
  
  Typical Use Cases
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Deploying infrastructure via Terraform or CloudFormation&lt;/li&gt;
&lt;li&gt;Automating tasks e.g., S3 uploads, Lambda management&lt;/li&gt;
&lt;li&gt;Integrating CI/CD workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Risk When Exposed
&lt;/h5&gt;

&lt;p&gt;If these keys are tied to an IAM user or role with broad permissions, an attacker can&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List and exfiltrate S3 buckets&lt;/li&gt;
&lt;li&gt;Spin up EC2 instances - for crypto mining or persistence&lt;/li&gt;
&lt;li&gt;Access RDS snapshots or EBS volumes&lt;/li&gt;
&lt;li&gt;Destroy resources or disable security services e.g., GuardDuty&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  GCP Service Account Keys
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy82xf3h41b9vhppla9ua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy82xf3h41b9vhppla9ua.png" alt="GCP SA Keys" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  What are they?
&lt;/h5&gt;

&lt;p&gt;A GCP &lt;a href="https://xebia.com/blog/how-to-create-your-own-google-service-account-key-file" rel="noopener noreferrer"&gt;service account key&lt;/a&gt; is a &lt;strong&gt;JSON file&lt;/strong&gt; that authenticates as a service account. It allows full API access according to the permissions granted to that account.&lt;/p&gt;

&lt;h5&gt;
  
  
  Typical Use Cases
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Interacting with GCP services e.g., Cloud Storage, Pub/Sub, BigQuery&lt;/li&gt;
&lt;li&gt;Running automated workloads in CI/CD pipelines&lt;/li&gt;
&lt;li&gt;Backend services or microservices accessing GCP APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Risk When Exposed
&lt;/h5&gt;

&lt;p&gt;With a leaked key, an attacker can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authenticate with &lt;strong&gt;&lt;em&gt;gcloud&lt;/em&gt;&lt;/strong&gt; to your cloud project. &lt;/li&gt;
&lt;li&gt;Access or modify GCS buckets.&lt;/li&gt;
&lt;li&gt;Interact with APIs e.g., Cloud SQL, IAM, Compute Engine.&lt;/li&gt;
&lt;li&gt;Move laterally across projects and regions, depending on scope.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real World Discovery: Resurrecting Cloud Credentials
&lt;/h3&gt;

&lt;p&gt;While hunting for vulnerabilities in a bug bounty program, I focused on a company's public GitHub repositories. One of the most overlooked areas in such assessments is &lt;strong&gt;Git history&lt;/strong&gt; — especially commits related to &lt;em&gt;&lt;strong&gt;CI/CD automation&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F70aj5ugr1w3lgjkj9q9h.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F70aj5ugr1w3lgjkj9q9h.gif" alt="phishing" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, I discovered that the organization had once committed credentials within &lt;em&gt;test configuration files&lt;/em&gt;, likely used for automation purposes during development. These files were later deleted — a move that gives a false sense of security to many developers 😂. But as any experienced hunter knows, deleting a file doesn't erase its past from Git.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fimrpqrq8numlbg2b2q93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fimrpqrq8numlbg2b2q93.png" alt="Git deleted" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using basic &lt;code&gt;git log&lt;/code&gt; and &lt;code&gt;git show&lt;/code&gt; commands, I located the commit hashes and recovered the deleted files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;diff&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;grep&lt;/span&gt; &lt;span class="k"&gt;delete&lt;/span&gt;
&lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;show&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;commit_hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there it was — the &lt;strong&gt;buried treasure&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Finding 1: AWS Key in a Test File
&lt;/h4&gt;

&lt;p&gt;Inside a deleted test config file, I discovered exposed AWS Access key as shown in the example below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;eu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;central&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;aws_access_key_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;AKIAIOSFODNN7EXAMPLE&lt;/span&gt;
&lt;span class="nx"&gt;aws_secret_access_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wJalrXUtnFEMI&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;K7MDENG&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;bPxRfiCYEXAMPLEKEY&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I immediately knew this was credentials for Frankfurt region  based on the profile setting of &lt;code&gt;test-s3-eu-central-1&lt;/code&gt; and I rushed to CLI to configure this and test the credentials&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="nx"&gt;configure&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="nx"&gt;orgName&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;eu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;central&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="nx"&gt;sts&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;caller&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="nx"&gt;orgName&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;eu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;central&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt; &lt;span class="nx"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second command above gave the below output in my CLI after configuring the profile confirming the credentials are active. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fddsf4jvh9e3gs06amfwf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fddsf4jvh9e3gs06amfwf.png" alt="AWS CLI Test" width="800" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It worked 😎. The credentials were still active, and the IAM user had access to several buckets and EC2 metadata 🤯. Some even contained staging environment snapshots — a serious data exposure.&lt;/p&gt;

&lt;h4&gt;
  
  
  Finding 2: GCP Service Account Key Recovered
&lt;/h4&gt;

&lt;p&gt;Another deleted commit in a different organization's public GitHub repo revealed a &lt;strong&gt;__&lt;em&gt;json_key&lt;/em&gt;&lt;/strong&gt; used for automated GCP deployments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqp8j6dy7kzuih7vie7gj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqp8j6dy7kzuih7vie7gj.png" alt="GCP SA creds" width="800" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I decoded the credentials from base64 encoding and then saved them to a file &lt;em&gt;org-sa-creds.json&lt;/em&gt; for authentication via &lt;strong&gt;gcloud&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;gcloud&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="nx"&gt;activate&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;org&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;
&lt;span class="nx"&gt;gcloud&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;
&lt;span class="nx"&gt;gcloud&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="nx"&gt;PROJECT&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ID&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bindings.members:serviceAccount:SERVICE-ACCOUNT-EMAIL@SOMETHING.iam.gserviceaccount.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;json
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final command above can be used to view GCP IAM policy of the service account. Please NOTE this can only be successful based on permissions given to the service account. &lt;/p&gt;

&lt;p&gt;Below is the service account authentication via &lt;em&gt;gcloud&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyraw4ocmhvsy3m274jrt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyraw4ocmhvsy3m274jrt.png" alt="gloud auth" width="800" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzhc8a06jym6egdpd2nb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzhc8a06jym6egdpd2nb.gif" alt="Elliot-seeing-this-too" width="480" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key was valid, and I was able to &lt;strong&gt;enumerate projects&lt;/strong&gt;, &lt;strong&gt;enumerate permissions&lt;/strong&gt;, &lt;strong&gt;list GCS buckets&lt;/strong&gt;, &lt;strong&gt;view/download bucket objects&lt;/strong&gt;, and access &lt;strong&gt;compute resources&lt;/strong&gt; — all tied to the target organization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consequences of Exposure
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Business Risk
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Data exfiltration and theft. &lt;/li&gt;
&lt;li&gt;Infrastructure hijack for crypto mining or botnets.&lt;/li&gt;
&lt;li&gt;Compliance violations e.g GDPR, HIPAA,etc..&lt;/li&gt;
&lt;li&gt;Reputation damage if incidents go public.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Attack Vector Expansion
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Persistence using created IAM users or service accounts.&lt;/li&gt;
&lt;li&gt;Privilege escalation via over-permissive roles.&lt;/li&gt;
&lt;li&gt;Lateral movement across multi-cloud or hybrid setups.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Lessons from the Shadows
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Scan before you commit - use tools like git-secrets and Gitleaks.&lt;/li&gt;
&lt;li&gt;Automate secrets detection - CI/CD pipelines should fail if secrets are detected.&lt;/li&gt;
&lt;li&gt;Use short-lived credentials - prefer IAM roles and workload identity over static keys.&lt;/li&gt;
&lt;li&gt;Audit and rotate - regularly audit credential usage and rotate keys periodically. But you know this rarely happens😁&lt;/li&gt;
&lt;li&gt;Restrict and monitor - apply least privilege and set up anomaly detection using resources like &lt;strong&gt;AWS GuardDuty&lt;/strong&gt;, &lt;strong&gt;GCP Security Command Center&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Cloud credentials are among the most powerful and dangerous secrets to leave in your Git history. In the wrong hands, they can become the demons that burn your cloud kingdom to the ground.&lt;/p&gt;

&lt;p&gt;This is the second tale of our git tales 😁. In the final tale of the Git Tales series, we’ll dive into:&lt;/p&gt;

&lt;p&gt;📝 Part 3: How committed Github tokens and Azure ACR creds can expose your private repos and container Images.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwd7lmsks5x5pmk1mm12h.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwd7lmsks5x5pmk1mm12h.gif" alt="Mr robot  organ " width="480" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"Stay vigilant. Stay paranoid. Your cloud deserves it! 🫠🫠🫠" - &lt;a class="mentioned-user" href="https://dev.to/davisbug"&gt;@davisbug&lt;/a&gt; &lt;/p&gt;

</description>
      <category>bugbounty</category>
      <category>infosec</category>
      <category>cloudsecurity</category>
      <category>pentest</category>
    </item>
    <item>
      <title>Git Tales: Secrets in the Shadows</title>
      <dc:creator>Peter Davis</dc:creator>
      <pubDate>Tue, 29 Apr 2025 12:10:28 +0000</pubDate>
      <link>https://forem.com/davisbug/git-tales-secrets-in-the-shadows-2n8b</link>
      <guid>https://forem.com/davisbug/git-tales-secrets-in-the-shadows-2n8b</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Part&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;Git&lt;/span&gt; &lt;span class="nx"&gt;Tales&lt;/span&gt; &lt;span class="nx"&gt;Series&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;In my recent bug hunting, I stumbled across something that perfectly shows why "deleted" doesn't always mean "gone." I discovered a particularly critical vulnerability that highlights a common oversight among developers, the misunderstanding of &lt;strong&gt;&lt;a href="https://octobot.medium.com/how-git-internally-works-1f0932067bee" rel="noopener noreferrer"&gt;Git history&lt;/a&gt;&lt;/strong&gt;. The target codebase had undergone multiple revisions, and one configuration file "&lt;strong&gt;appsettings.json&lt;/strong&gt;" had been deleted in a recent commit.&lt;/p&gt;

&lt;p&gt;Curious, I ran a quick scan of the Git history using tools like &lt;code&gt;git log&lt;/code&gt; and &lt;code&gt;git diff&lt;/code&gt;. To my surprise, the deleted file had once contained &lt;a href="https://shopify.dev/docs/apps/build/authentication-authorization/access-tokens/generate-app-access-tokens-admin" rel="noopener noreferrer"&gt;Shopify Admin API keys&lt;/a&gt; — plaintext credentials capable of granting administrative access to a Shopify store.&lt;/p&gt;

&lt;p&gt;This wasn’t a file accidentally left in the final commit. It was a deleted file that had been committed earlier, still lingering in the repository’s history. This sort of vulnerability is often overlooked because many developers assume that once a file is deleted and pushed, it's gone. Git, however, retains every commit unless explicitly scrubbed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Impact of the Vulnerability
&lt;/h3&gt;

&lt;p&gt;The leaked Admin API token for Shopify was still valid when discovered and belonged to a store that had gone live in January 2025. The potential impact was significant and included:&lt;/p&gt;

&lt;h4&gt;
  
  
  Full Administrative Access 🔓
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Read, update, and delete orders, products, customers, inventory, and themes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manage discount codes and price rules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add malicious ScriptTags to inject JavaScript into the storefront.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Data Breach Risk 📊
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Exposed customer PII (names, emails, order history).&lt;/li&gt;
&lt;li&gt;Violated data protection regulations like the GDPR.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftofh0o1ki4ty0mkey87z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftofh0o1ki4ty0mkey87z.png" alt="Customer PII" width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Disruption of Store Operations 🛠
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Unauthorized configuration changes&lt;/li&gt;
&lt;li&gt;Loss or corruption of data&lt;/li&gt;
&lt;li&gt;Deletion of products or categories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, a valid Admin API key, even for a development store, has access to production-level functionality. This creates an enormous attack surface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proof of Concept (PoC) and Bounty
&lt;/h3&gt;

&lt;p&gt;To responsibly demonstrate the impact, I conducted a limited set of read-only API calls using &lt;code&gt;curl&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Get store information
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;X&lt;/span&gt; &lt;span class="nx"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-Shopify-Access-Token: &amp;lt;admin_api_key&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt;
  &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//&amp;lt;storename&amp;gt;.myshopify.com/admin/api/2024-01/shop.json&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  List all products
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;X&lt;/span&gt; &lt;span class="nx"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-Shopify-Access-Token: &amp;lt;admin_api_key&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt;
  &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//&amp;lt;storename&amp;gt;.myshopify.com/admin/api/2024-01/products.json&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  View access scopes
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;X&lt;/span&gt; &lt;span class="nx"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-Shopify-Access-Token: &amp;lt;admin_api_key&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt;
  &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//&amp;lt;storename&amp;gt;.myshopify.com/admin/oauth/access_scopes.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last API call (&lt;code&gt;access_scopes.json&lt;/code&gt;) confirmed that the token had read permissions across major endpoints as shown in the diagram below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fonss9p6v8u0tnuqsb7rd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fonss9p6v8u0tnuqsb7rd.png" alt="Access scopes" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Responsible Disclosure ✅
&lt;/h3&gt;

&lt;p&gt;The vulnerability was reported via the appropriate bug bounty platform. The organization responded quickly, revoked the token, and awarded a bounty for the finding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Properly Remove Secrets from Git History
&lt;/h3&gt;

&lt;p&gt;Many developers know how to delete a file from a repo, but far fewer understand that Git never forgets. A simple &lt;code&gt;git rm&lt;/code&gt; followed by a commit only removes the file from the working directory — not from history.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step-by-Step: Clean Your Git History 🧼
&lt;/h4&gt;

&lt;p&gt;Option 1: Using &lt;a href="https://rtyley.github.io/bfg-repo-cleaner/" rel="noopener noreferrer"&gt;BFG Repo-Cleaner&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Delete a file from all history&lt;/span&gt;
bfg &lt;span class="nt"&gt;--delete-files&lt;/span&gt; config.json

&lt;span class="c"&gt;# Remove secrets from history using a list&lt;/span&gt;
bfg &lt;span class="nt"&gt;--replace-text&lt;/span&gt; passwords.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Option 2: Using &lt;code&gt;git filter-branch&lt;/code&gt; &lt;br&gt;
Kindly note this method is slower but more flexible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;force&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;git rm --cached --ignore-unmatch config.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;prune&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;empty&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Important
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Force-push after cleaning. Commands below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;force&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;
&lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;force&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Rotate any secrets found in history. Very Important!!!!!!!!!&lt;/li&gt;
&lt;li&gt;Re-clone the repository to avoid residuals.&lt;/li&gt;
&lt;li&gt;Notify all collaborators so they can do the same.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhlpuw8safv77j6hzpm8v.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhlpuw8safv77j6hzpm8v.gif" alt="Paranoid Elliot" width="480" height="270"&gt;&lt;/a&gt; &lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This finding is a prime example of how code history can betray your security efforts. Developers often overlook &lt;strong&gt;deleted files&lt;/strong&gt;, unaware that a &lt;em&gt;sensitive credential&lt;/em&gt; committed even once can remain accessible unless explicitly purged.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Takeaways
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Deleting a file doesn't delete it from Git history.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Admin API keys in Shopify offer massive control and should be treated like passwords.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Always audit code and Git history before pushing public repositories or publishing code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use automated scanners during CI/CD to catch secrets before they go live.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;This is just the beginning. In the next parts of the Git Tales series, we’ll dive into:&lt;/p&gt;

&lt;p&gt;🧩 Part 2: How Service account keys can be your demons in the cloud.&lt;br&gt;
📝 Part 3: How committed Github tokens can expose your private repos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgk82x9qjd53k1y5a3j0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgk82x9qjd53k1y5a3j0.gif" alt="Elliot" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Until then, treat your Git repo like an open diary — someone might be reading.&lt;/p&gt;

</description>
      <category>bugbounty</category>
      <category>infosec</category>
      <category>pentest</category>
      <category>sourcecodereview</category>
    </item>
    <item>
      <title>Bug Bounty Hidden Treasures</title>
      <dc:creator>Peter Davis</dc:creator>
      <pubDate>Wed, 26 Mar 2025 06:40:39 +0000</pubDate>
      <link>https://forem.com/davisbug/bug-bounty-hidden-treasures-59lb</link>
      <guid>https://forem.com/davisbug/bug-bounty-hidden-treasures-59lb</guid>
      <description>&lt;h2&gt;
  
  
  What's Bug Bounty
&lt;/h2&gt;

&lt;p&gt;Bug bounty is a monetary reward given to ethical hackers for successfully discovering and reporting a vulnerability or bug in an application, API, or computer system. Bug bounty programs allow companies to leverage the &lt;em&gt;&lt;strong&gt;hacker community&lt;/strong&gt;&lt;/em&gt; to improve their systems’ security posture over time continuously.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hidden Treasures
&lt;/h2&gt;

&lt;p&gt;Bug bounty hunters thrive on uncovering vulnerabilities that others overlook, and some of the most rewarding finds come from hidden routes within an application. These routes, often undocumented or left exposed due to misconfigurations, can lead to critical areas such as admin panels, debug endpoints, or forgotten API endpoints. Attackers who discover these paths can manipulate backend systems, access sensitive data, or even take control of critical functionalities. By carefully mapping an application’s structure and testing unconventional input, hunters can reveal these concealed attack surfaces.&lt;/p&gt;

&lt;p&gt;Another lucrative area for discovery lies in deployed but unknown features—those pushed into production without proper security vetting. Developers sometimes leave experimental or beta functionalities accessible via specific parameters or headers, unaware that they can be exploited. These features may bypass authentication, introduce unintended behaviors, or expose sensitive internal tools. A skilled hunter knows how to probe for such hidden mechanisms by analyzing application requests, reviewing JavaScript files, and testing feature flags to unlock functionalities that shouldn’t be publicly accessible.&lt;/p&gt;

&lt;p&gt;Decommissioned features lingering in production are another goldmine. Organizations may retire certain functionalities but fail to fully remove their backend components, leaving old endpoints or outdated authentication mechanisms still operational. These forgotten elements often lack modern security protections, making them prime targets for exploitation. By identifying and testing legacy endpoints or accessing outdated documentation, hunters can uncover these remnants and turn them into high-value reports before malicious actors do.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Found One of Those Treasures
&lt;/h2&gt;

&lt;p&gt;I've been doing bug bounties since 2018, and over the years have learned a thing or two on how to approach a target that may seem difficult or unhackable. I had a &lt;strong&gt;target.com&lt;/strong&gt; that I found online that offers great bounties for their cloud assets. After the enumeration of all subdomains, I picked one that looked interesting to hack on. &lt;/p&gt;

&lt;p&gt;I utilized &lt;a href="https://github.com/ffuf/ffuf" rel="noopener noreferrer"&gt;ffuf&lt;/a&gt; to enumerate directories since it's faster and also has great flags that can help you get the results you want. I discovered quite a number of directories that looked like normal stuff and un interesting. I then discovered one called "/&lt;strong&gt;system&lt;/strong&gt;/ which seemed more interesting and fun to probe further.  I fuzzed it, and then I discovered an endpoint "/system/auth" that allowed users to authenticate to the application via a login form, as shown below. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxctqrz4upm7z5kbncdtr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxctqrz4upm7z5kbncdtr.png" alt="Application Authentication" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was not the normal endpoint for authentication to that application, but a way system administrators used to get to the application. The fun bit of it was that they used default credentials to access the console as shown above. This may seem like a trivial hack, but its impact was massive to the organization since the console was a central place where multiple client workloads were, as shown below &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg3nb3hw1i9j88mvg2gej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg3nb3hw1i9j88mvg2gej.png" alt="Console Admin Access" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above finding paid a 4-figure bounty. Sounds easy but gets paid a lot based on impact&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhkogfimjdyuts04o2bz8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhkogfimjdyuts04o2bz8.png" alt="Invoice for the bounty" width="800" height="798"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;Based on the example given above,  hidden elements present high-value opportunities for bug bounty hunters who know where to look. Some of the things to look for are:&lt;/p&gt;

&lt;h3&gt;
  
  
  Hidden Routes in Applications
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Undocumented admin panels, debug endpoints, and API paths can expose critical functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mapping an application’s structure helps reveal concealed attack surfaces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exploiting misconfigurations in routing can lead to data leaks or privilege escalation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deployed but Unknown Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Experimental or beta features may be accessible via hidden parameters or headers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Poorly tested functionalities can bypass authentication or introduce unintended behaviors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reviewing JavaScript files and application requests can expose hidden features.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Decommissioned Features in Production
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Retired functionalities may still have active backend components, creating security gaps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Legacy endpoints often lack modern security protections, making them easy targets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accessing outdated documentation or API references can uncover forgotten vulnerabilities.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Finding hidden treasures in bug bounty hunting requires patience, curiosity, and a keen eye for overlooked vulnerabilities. Whether it's discovering undocumented routes, probing deployed but forgotten features, or exploiting remnants of decommissioned functionalities, these hidden gems often lead to significant security findings. Skilled hunters who think outside the box, analyze applications thoroughly, and test unconventional attack surfaces can uncover critical weaknesses before malicious actors do. In the ever-evolving world of cybersecurity, the real rewards lie in what others fail to see. Keep digging—you never know what hidden bounty awaits! 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Cloud Resume Challenge - GCP :)</title>
      <dc:creator>Peter Davis</dc:creator>
      <pubDate>Sun, 11 Sep 2022 08:11:41 +0000</pubDate>
      <link>https://forem.com/davisbug/the-cloud-resume-challenge-gcp--4o11</link>
      <guid>https://forem.com/davisbug/the-cloud-resume-challenge-gcp--4o11</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;In July 2022 I came across the &lt;a href="https://cloudresumechallenge.dev/docs/the-challenge/" rel="noopener noreferrer"&gt;cloud resume challenge&lt;/a&gt; by &lt;a href="https://forrestbrazeal.com" rel="noopener noreferrer"&gt;Forrest Brazeal&lt;/a&gt; shortly after completing my &lt;a href="https://www.credential.net/fe0fe2ad-e16f-4f2f-ac73-f44b3f937eec" rel="noopener noreferrer"&gt;Cloud Engineer&lt;/a&gt; Certification by Google Cloud. The challenge was forwarded to me by mentor &lt;strong&gt;Martin&lt;/strong&gt; and immediately after having an overview of the tasks I knew the challenge was good enough to piece together all I had learned about GCP.   &lt;/p&gt;

&lt;p&gt;The Resume challenge itself is simple but enables one to stitch together different functionalities of the cloud and come up with a complete workflow of building a static website which is fully hosted on cloud resources. Below is how I did the challenge:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Certification
&lt;/h2&gt;

&lt;p&gt;The challenge required one to have at least completed &lt;a href="https://cloud.google.com/certification/cloud-digital-leader" rel="noopener noreferrer"&gt;Google Cloud Digital Leader&lt;/a&gt; by Google. Fortunately I had completed &lt;a href="https://www.credential.net/fe0fe2ad-e16f-4f2f-ac73-f44b3f937eec" rel="noopener noreferrer"&gt;Associate Cloud Engineer&lt;/a&gt; by Google early July 2022 and I was comfortable building and hosting applications on GCP.  &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Static Website
&lt;/h2&gt;

&lt;p&gt;The challenge prompted one to write a static site for their resume in HTML &amp;amp; CSS. This was a quick task for me having done a bit of systems development early on in my career, picked up a template online for the look and feel of the site and created custom CSS to make it look better. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4k7323c8xgco9kx6leae.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4k7323c8xgco9kx6leae.png" alt="My Resume site" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Site Hosting
&lt;/h2&gt;

&lt;p&gt;The static site (Resume) is supposed to be hosted on &lt;a href="https://cloud.google.com/storage" rel="noopener noreferrer"&gt;Google Cloud Storage&lt;/a&gt; and use a cloud load balancer for traffic flow. I used GCP storage bucket to host the site while Cloud Load Balancing via HTTP(S) Load Balancer on GCP. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;bucket creation config&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="c1"&gt;#site bucket&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;resume.hexorsec.com&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gcp-types/storage-v1:buckets&lt;/span&gt;
  &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;zone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-central1-f&lt;/span&gt;
    &lt;span class="na"&gt;website&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;mainPageSuffix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;
      &lt;span class="na"&gt;notFoundPage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;
    &lt;span class="na"&gt;iamConfiguration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;uniformBucketLevelAccess&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;davisresume&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTTPS certificate&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Put the bucket as a backend service&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;davis-resume-backend-bucket&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gcp-types/compute-v1:backendBuckets&lt;/span&gt;
  &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;bucketName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$(ref.hexorsec.resume.com.name)&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Backend bucket for the CDN&lt;/span&gt;
    &lt;span class="na"&gt;enableCdn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="c1"&gt;# Create an HTTPS certificate&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;davis-resume-https-cert&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gcp-types/compute-v1:sslCertificates&lt;/span&gt;
  &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MANAGED&lt;/span&gt;
    &lt;span class="na"&gt;managed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;domains&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;$(ref.resume.hexorsec.com.dnsName)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. DNS
&lt;/h2&gt;

&lt;p&gt;The site is supposed to be pointed to a custom DNS domain name. My domain is already registered on Godaddy and I had just to add an entry for the site. Using the IP address of the Load balancer  I created an entry for my &lt;a href="https://resume.hexorsec.com" rel="noopener noreferrer"&gt;resume&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  5. Visitor Count
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftr0nfwttqp39hk86m178.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftr0nfwttqp39hk86m178.png" alt="Visitor Counter" width="648" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The challenge prompted one to have a section on the site for number of visitors who visit the site. For this I wrote a simple JavaScript code to fetch JSON content from endpoints and update visitor count on my site. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Firestore&lt;/strong&gt;&lt;br&gt;
I used Firestore to store and update visitor count object on the site. The database is automatically created by a script when the first visitor reaches the website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API&lt;/strong&gt;&lt;br&gt;
The communication between JavaScript code and database is managed by a cloud function on GCP which I created. The function depends on HTTP triggers to invoke an event. The function:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;reads the visitor count from firestore database&lt;/li&gt;
&lt;li&gt;increments it by one&lt;/li&gt;
&lt;li&gt;saves it to the database&lt;/li&gt;
&lt;li&gt;returns the value to the client.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  6. Python &amp;amp; Tests
&lt;/h2&gt;

&lt;p&gt;The challenge prompts us to use python to write the serverless function and then perform some tests on our written code.&lt;br&gt;
For this I used Python3.6 to write the serverless function and the communication between code and the backend db uses the google-cloud-firestore Python library. &lt;/p&gt;
&lt;h2&gt;
  
  
  7. Tests &amp;amp; Security
&lt;/h2&gt;

&lt;p&gt;I used &lt;a href="https://pylint.pycqa.org/en/latest" rel="noopener noreferrer"&gt;Pylint&lt;/a&gt; to perform basic test on the code and for the security bit I used &lt;a href="https://snyk.io/" rel="noopener noreferrer"&gt;snyk&lt;/a&gt; SCM to check for vulnerabilities within my code and it's dependencies. &lt;/p&gt;
&lt;h2&gt;
  
  
  8. IAC, CI/CD &amp;amp; Source Control
&lt;/h2&gt;

&lt;p&gt;The challenge goes a head and prompt us to do a bit of IAC for automation purposes between the function, firestore and API gateway. The IAC allows one to replicate and do updates easily on the infra being provisioned. I opted to go with Deployment Manager as is an easy way to do quick deployments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static Site Syncing&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="c1"&gt;# Copy the Site content to a GS bucket&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gcr.io/google.com/cloudsdktool/cloud-sdk:latest'&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Sync the website content&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gsutil'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-m'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;rsync'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-r'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;site/'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gs://resume.hexorsec.com'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fib64td1a7scrqf8x3jsv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fib64td1a7scrqf8x3jsv.png" alt="Static Site Trigger" width="800" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pylint Scanning&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="c1"&gt;# Pylint SAST&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python:3.6&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check the python package&lt;/span&gt;
  &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;bash'&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-c'&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;|-&lt;/span&gt;
      &lt;span class="s"&gt;pip install pylint&lt;/span&gt;
      &lt;span class="s"&gt;pip install -r scripts/visitor_count/requirements.txt&lt;/span&gt;
      &lt;span class="s"&gt;pylint scripts/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80o81zirn07uwcjv1e02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80o81zirn07uwcjv1e02.png" alt="Pylint checking Packages" width="800" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infra as Code&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Deploy&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gcr.io/google.com/cloudsdktool/cloud-sdk:latest'&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy the infrastructure&lt;/span&gt;
  &lt;span class="na"&gt;entrypoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;bash'&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-c'&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;|-&lt;/span&gt;
      &lt;span class="s"&gt;apt install -y zip&lt;/span&gt;
      &lt;span class="s"&gt;pushd scripts/visitor_count&lt;/span&gt;
      &lt;span class="s"&gt;zip -r ../visitor_count.zip .&lt;/span&gt;
      &lt;span class="s"&gt;cd ..&lt;/span&gt;
      &lt;span class="s"&gt;file_name="count_$(md5sum visitor_count.zip | awk '{print $1}').zip"&lt;/span&gt;
      &lt;span class="s"&gt;mv visitor_count.zip ${file_name}&lt;/span&gt;
      &lt;span class="s"&gt;gsutil cp ${file_name} gs://hexorsec-XXXX-YYYYYYY&lt;/span&gt;
      &lt;span class="s"&gt;popd&lt;/span&gt;
      &lt;span class="s"&gt;gcloud deployment-manager deployments update resume-xxx-depl&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Cloud Build&lt;/strong&gt;&lt;br&gt;
For the build I created two triggers for Infra and static site. With the two build triggers once changes are made to github and action is triggered for syncing and pushing changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F26z2tq6090ph860b4yyy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F26z2tq6090ph860b4yyy.png" alt="Cloud Build Triggers" width="800" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Blog Post
&lt;/h2&gt;

&lt;p&gt;Finally the challenge prompted one to create a blog post describing the entire process of the challenge. Here is the post for that :) &lt;/p&gt;

&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;Going through the challenge is one of the best things have done after acquiring the associate cloud engineer cert from google. The entire process showed me how things work in the cloud and how use-cases can be created in such scenarios. I'm so grateful to &lt;a href="https://forrestbrazeal.com/" rel="noopener noreferrer"&gt;Forrest Brazeal 👏&lt;/a&gt; for setting up such a great challenge and my Mentor &lt;a href="https://www.linkedin.com/in/martin-kariuki" rel="noopener noreferrer"&gt;Martin 🫡&lt;/a&gt; for pointing me to such amazing resource for learning. &lt;/p&gt;

</description>
      <category>devops</category>
      <category>python</category>
      <category>cloud</category>
      <category>gcp</category>
    </item>
  </channel>
</rss>
