Storybooks › Cybersecurity for Juniors, Book 2 › Chapter 3

Naina (long black hair in a ponytail, glasses) and Rehan (lean build, messy curly hair, laptop covered in CTF/bug-bounty stickers) hunched over one laptop in a dim hostel common room late at night, energy drink cans nearby, a countdown clock visible on a phone propped against a water bottle.Illustrated with AI

Cybersecurity for Juniors · Book 2 · Chapter 3

The Group Project Repo

Big idea: a secret in your code is a secret for everyone who can see the codeClasses 9–12 & College

Part 1 · CampusConnect, due at 9 a.m.

Naina and Rehan's first real coding assignment was small on paper and enormous at 1 a.m.: a web form called CampusConnect, where students could submit feedback about hostel food, and the app would email a tidy weekly summary to the mess committee automatically.

The emailing part needed a transactional email service, the kind that hands out a free "API key," a long string of letters and numbers that proves to the service it's really your app asking it to send mail, and not someone else's.

They signed up, got their key, pasted it somewhere in the code that worked, and moved on, the way anyone does at 1 a.m. with a 9 a.m. deadline.

Part 2 · The 1 a.m. shortcut

"Somewhere in the code" turned out to be directly inside main.py, in plain text, right next to the line that sent the email: API_KEY = "sk_live_7hT9k2...". It worked immediately, which at 1 a.m. felt like the only thing that mattered.

Sanjeev sir's instructions asked them to push the finished project to a public GitHub repository, so he could clone it and check it ran. Rehan did exactly that, half-asleep, without a second thought for what else was sitting inside main.py the moment it went public.

"Submitted," he said, closing the laptop. "Sleep now, worry later."

Part 3 · A message from someone called quietpatch0x

Naina (long black hair in a ponytail, glasses) looking at her phone with a confused, wary expression, reading a GitHub notification email on screen in a sunlit classroom, Rehan beside her leaning in to read too.Illustrated with AI

Three days later, a notification landed on the CampusConnect repository: a new "issue," titled simply, "Please rotate your email API key, it's exposed in main.py." The message, from a GitHub account called quietpatch0x, was short, polite, and included a direct link to the exact line.

Naina's first reaction wasn't relief. It was suspicion. "Is this a scam?" she asked. "Someone messaging us out of nowhere, about a 'problem,' telling us to act fast?"

It did sound, uncomfortably, like the kind of message they'd learned to distrust by now. The difference, she realised on a second read, was that this one asked them to fix something themselves, on their own account, and wanted nothing from them in return. No link to click, no payment, no document.

Part 4 · Checking with Ananya didi, just in case

Ananya didi read the issue, then the code, then let out a small laugh that wasn't unkind. "It's real," she said. "And quietpatch0x did exactly the right thing. This is called responsible disclosure: finding a security problem and reporting it quietly to the people who can fix it, instead of using it, selling it, or posting it publicly for anyone to grab."

She pulled up the repository's commit history, still fully public. "Public GitHub repos get scanned constantly, by researchers, and by automated bots looking for exactly this pattern, 'sk_live_' followed by a long string. Some bots report it like quietpatch0x did. Others just use it. You got the better kind of attention first, this time."

Part 5 · Sanjeev sir, and the thing about git history

Sanjeev sir (short dark hair receding at the front, trimmed beard, rimless glasses, navy blue t-shirt) at a classroom whiteboard, sketching a simple timeline of git commits, Naina and Rehan watching attentively from the front row.Illustrated with AI

Sanjeev sir, once looped in, didn't lecture about the mistake itself, every student made it once. He wanted them to understand the part that surprised most people: "If you simply delete that line in a new commit, the key doesn't disappear. It's still sitting in an earlier commit, in the project's full history, which anyone can still browse."

He sketched it on the whiteboard: commit one has the key, commit two removes it, but commit one still exists, forever, unless someone deliberately rewrites history with a tool built for exactly that. "Treat any secret that's ever been committed as burned," he said. "Rotate it. Don't just hide it."

Part 6 · Rotating the key, properly this time

They logged into the email service and revoked the old key within the hour, generating a fresh one. This time, the key went into a separate file named .env, which they added to a new file called .gitignore, a list of files Git is told to never track or upload, ever.

The code itself changed by exactly one line: instead of a string typed directly in, it now read the key from the environment, os.environ.get("API_KEY"), invisible to anyone looking at the public code, present only on the machine actually running it.

Checking the service's usage logs, relief: the free-tier key had a strict sending cap, and nobody had used it for anything in the three days it sat exposed. "We got lucky," Naina said. "Lucky isn't a plan," Ananya didi replied, not unkindly.

Part 7 · Rehan wants to be quietpatch0x next

Rehan couldn't stop thinking about the message, less about the mistake it pointed out, more about the person who'd found it. "How does someone even find stuff like that?" he asked. "On purpose? Legally?"

"That's a whole world," Ananya didi said, amused. "Ethical hacking, done properly, with rules. Ask me again once you're sure you want the real answer, not just the exciting-sounding one."

Rehan was already sure. He just didn't yet know how close that curiosity would come to getting him into real trouble, barely a week later.

Moral of the story

A secret typed into public code is no longer a secret. The fix isn't hiding it better. It's never writing it there at all.

What's pushed in haste at one a.m.
stays written down for who, and when.
A key once shown to open eyes
must be replaced, not just disguised.

Spot the problems in this code

main.py, pushed at 1 a.m.

A snippet from CampusConnect's public repository:

API_KEY = "sk_live_7hT9k2xPq..." 1
DB_PASSWORD = "campus2026!" 2

No .gitignore file anywhere in the project. 3

Repository visibility: Public, visible to anyone on the internet. 4

1

A live API key, typed directly into the source code. Anyone who can see the code can now send email, or run up usage, on this account.

2

A database password, in plain text, right next to the key. One leaked file, two separate systems now exposed.

3

Nothing tells Git to keep sensitive files out of what gets uploaded, so anything created locally can end up public by default.

4

A public repository is scanned by bots within minutes of a push, looking for exactly these patterns. Public means public to everyone, immediately.

Field notes

What really happened?

In the storyThe real idea
The API key typed directly into main.pyHardcoded secret: a password, key, or token written straight into source code instead of kept separately
quietpatch0x's polite GitHub issueResponsible disclosure: reporting a security problem quietly to whoever can fix it, instead of exploiting or publicising it
"Deleting the line doesn't remove it from history"Git keeps every past version of a file; a secret committed once is considered exposed forever unless history itself is rewritten
Moving the key into a .env fileEnvironment variables: a way to supply secrets to running code without ever writing them into the code itself
The new .gitignore fileA list of files and patterns Git is told never to track, keeping sensitive files out of what gets uploaded in the first place
Bots scanning public repositories for key patternsSecret scanning: automated tools, run by GitHub, providers, and independent researchers, that watch for exposed credentials at scale
The free-tier sending cap that limited the damageA spending or usage limit is a safety net, not a plan; the real fix is never exposing the secret in the first place

Try it yourself

Secret exposed, or safely handled?

Here are four lines you might find in a real project. Tap one to see whether it's a safe practice or a leaked-secret risk, and why.

Tap a line above to check it.

Maths corner

What a leaked key can actually cost

Say a leaked API key has no spending cap, and once found, an attacker's script fires 1,000 requests every second, each costing the account holder ₹0.15. That's 1,000 × ₹0.15 = ₹150 per second.

Your turn. At that rate, how much does one minute cost? One hour? And if quietpatch0x's report had instead taken 3 hours to arrive, with the key already found and used by someone less polite, roughly how much could have been lost?

Answer: ₹150 × 60 = ₹9,000 per minute, and ₹9,000 × 60 = ₹5,40,000 per hour. Over 3 unlucky hours, that's roughly ₹16,20,000, entirely from one line of code and no spending cap, which is exactly why CampusConnect's free-tier cap, and a fast report, mattered so much.

Try it on a computer · optional

The fix: reading secrets from the environment

# the risky way, a secret baked right into the code
API_KEY = "sk_live_7hT9k2xPq..."

# the safer way, read from the environment instead
import os
API_KEY = os.environ.get("API_KEY")

if not API_KEY:
    raise ValueError("Set API_KEY as an environment variable before running this.")

The second version never contains the real key anywhere in the code, so pushing it to a public repository leaks nothing. The key lives only in a local .env file, which .gitignore keeps out of every commit.

Run this in any free online Python editor. Try removing the os.environ.get(...) line and hardcoding a fake key instead, then imagine that file being pushed to a public repository, which version would you rather have written?

Security tip

Five habits for every project repository

Add a .gitignore file before writing a single line of code, not after. Never type a real key, password, or token directly into a source file, use environment variables or a secrets manager from day one. Treat any secret that's ever been committed, even briefly, as compromised, and rotate it rather than simply deleting the line. Set spending or usage caps wherever a service allows it. And if someone reports a leaked secret to you, however the message arrives, say thank you before you question it, politely reported problems deserve a fast fix, not suspicion.

Did you know?

Fun facts

Found in minutes, not monthsAutomated secret-scanning bots routinely find exposed keys in newly pushed public code within minutes of the push, sometimes faster than the developer who pushed it notices their own mistake.
History really is foreverDeleting a file in a new commit does not remove it from a repository's history. Specialised tools exist purely to rewrite history and permanently purge a leaked secret, a far more involved fix than just editing a file again.
A whole category of real breachesA significant number of real-world data breaches, across companies of every size, trace back to a single credential accidentally committed to a public code repository, not a sophisticated attack at all.
Bounties exist for exactly thisMany companies run official bug bounty programs specifically so researchers like quietpatch0x can report findings like this one safely, sometimes even for a cash reward, instead of having no clear legitimate way to help.

Myth or fact?

"If I delete the line with the secret in my next commit, it's gone."

Myth

A new commit only adds a new snapshot. Every earlier snapshot, including the one with the exposed secret, still exists in the project's full history and remains visible to anyone who looks. The only real fix is rotating the secret itself, treating anything ever committed as burned, regardless of how quickly it was "removed" afterward.

Try this · no computer needed

Spot the secret

You need: paper and a pen, and at least one other person.

  1. One person writes out eight short, made-up lines of "code" on paper, ordinary variable assignments, with two of them secretly containing a fake password or key written in plain text.
  2. The other person has sixty seconds to read all eight lines and circle the ones they think are unsafe to push to a public repository.
  3. Reveal the answers, then discuss: what made the risky lines stand out, or not stand out, at a glance?
  4. Swap roles with a new set of eight lines, then discuss: how might a tool catch what a quick human read misses?

Careers corner

Application security (AppSec) engineer

An AppSec engineer works with developers before code ever reaches production, reviewing it for exactly these kinds of mistakes, hardcoded secrets, unsafe handling of user data, missing permission checks, and building automated tools that catch them early. It's a career that sits between software development and security, equally comfortable reading code and explaining risk.

Useful to learn: at least one programming language well, secure coding patterns, how version control systems like Git actually work, and the patience to explain a fix clearly to a developer under deadline pressure.

Quiz time

How well did you learn?

Score: 0 / 8

Think and discuss

No wrong answers here

  • Naina's first instinct was to suspect quietpatch0x's message was itself a scam. What made it different from the scam messages in earlier chapters, once she looked closer?
  • Rehan pushed the code half-asleep at 1 a.m. How much of this chapter's mistake was really about security knowledge, and how much was about deadline pressure and tiredness?
  • Why might a company reward someone for reporting a security flaw instead of punishing them for finding it?
  • If you found a real exposed password in someone else's public project tomorrow, what would you do first?

Be curious

Ask a teacher, parent or engineer

Have you ever accidentally shared a password or key, at work or in a project? What's an API key, in your own words? Does your workplace use anything like environment variables or a secrets manager? What would you do if a stranger reported a security problem in something you built? Have you ever heard of a real company losing money because of an exposed key?

Word bank

New words from this chapter

Hardcoded secret: a password, key, or token written directly into source code instead of kept separately.
Responsible disclosure: reporting a security flaw quietly to whoever can fix it, instead of exploiting or publicising it.
Environment variable: a way to supply a secret to running code without ever writing it into the code itself.
.gitignore: a file that tells Git which files and patterns to never track or upload.
Secret scanning: automated tools that watch public code for exposed credentials.
Credential rotation: replacing a leaked key or password with a fresh one, rather than only hiding the old one.

For teachers and parents: this chapter fits two 40-minute periods. Period 1: read Parts 1 to 7 aloud (15 min), explore the "secret exposed or safely handled" interactive together (10 min), then the Maths corner (10 min). Period 2: "Spot the problems in this code" discussion, the "spot the secret" activity, and the quiz. The key ideas: secrets belong in environment variables, never directly in code; Git history keeps every past version, so a deleted line is not a removed secret; responsible disclosure is how security researchers report problems ethically; and a usage cap is a safety net, not a substitute for not leaking the secret at all. The Python corner is optional and uses only the concept of environment variables, no actual exploitation. All chapter illustrations are AI-generated scene art (pending for this draft); the code panel and secret-picker are built by hand.