← Back to Learning Hub

Lesson 10: Secrets, Obscurity & Social Engineering

Picking up from last lesson — examples and hands-on challenges throughout

60 minutes Year 12 Content High Exam Priority

Part 1: Quick Recap — Last Lesson 5 min

Last lesson we covered SQL injection, XSS, CSRF, and started APIs. Before diving in, let's make sure those three attacks are locked in. Click each card to check your understanding.

πŸ’‰

SQL Injection

How does it work? What stops it?

Click to reveal

Attack: User input is concatenated into a SQL query, letting attackers alter its structure (e.g., admin'-- comments out the password check).

Defence: Parameterised queries β€” define the query structure first, pass user input separately as data it can never alter.
🧩

XSS

What does it target? One-line fix?

Click to reveal

Attack: Malicious JavaScript injected into a page and executed in other users' browsers. Happens when user content is inserted with innerHTML.

Defence: Use textContent β€” the browser treats the value as plain text, not parseable HTML.
πŸͺ

CSRF

What does it exploit? How stopped?

Click to reveal

Attack: A malicious site tricks your browser into making a request to a site you're logged into β€” your session cookie attaches automatically.

Defence: CSRF tokens β€” a secret value embedded in forms that an attacker on a different origin can't read or forge.

Where We Left Off

You know what an API is (a way for software to talk to external services) and why API keys exist (they authenticate you to the service and are tied to your account for billing). Today we cover what goes wrong when those keys end up exposed β€” and three more vulnerability classes to finish the picture.

Part 2: Hardcoded Secrets & Environment Variables 15 min

NESA SE-12-07 — Vulnerabilities

The Vulnerability — Hardcoded Secrets

What Are Hardcoded Secrets?

A hardcoded secret is any sensitive value β€” API key, password, database credential, private token β€” written directly into source code. It's the fastest way to get something working, which is why it happens constantly. But source code travels everywhere: pushed to GitHub, shared with collaborators, deployed to servers, cached by build tools, sometimes accidentally made public.

Every place your code goes, your secret goes with it.

πŸ” Challenge β€” Spot the Secret

Each snippet below contains a hardcoded secret. Click on the part you think is the problem to reveal what's wrong and why it matters.

Snippet A β€” Python backend
import requests

API_KEY = "sk-proj-abc123def456ghi789jkl"

response = requests.get(
    "https://api.openai.com/v1/chat/completions",
    headers={"Authorization": f"Bearer {API_KEY}"}
)
🚨 Found it. The OpenAI API key "sk-proj-abc123..." is hardcoded. Anyone who sees this file β€” through GitHub, a shared terminal, or a code review β€” can make API calls billed to your account. Automated bots typically exploit exposed keys within 4–7 minutes of a public commit. Developers have received five-figure cloud bills from a single exposure.
Snippet B β€” JavaScript config
const config = {
  appName: "VolcanicPantheon",
  theme: "dark",
  dbPassword: "VolcPanth#2025!",
  version: "1.2.0"
};
🚨 Found it. The database password is sitting in a JS config object. This file will likely be bundled and deployed β€” and JavaScript files are always readable in DevTools, even on production sites. It'll also end up in git history the moment it's committed.
Snippet C β€” Python auth check
def check_password(user_input):
    # Hash of "admin2025"
    CORRECT_HASH = "299957fa31b8e7784f4f7972..."
    return hash(user_input) == CORRECT_HASH
🚨 Found it β€” and the comment makes it worse. The comment reveals the original password was "admin2025". An attacker with the hash can run a dictionary attack or check a rainbow table. Even without the comment, the hash itself reveals which algorithm you're using and gives attackers a head start on cracking it.

The Git History Problem

If you commit a secret and then delete it in the next commit, the secret still exists in your git history forever. Anyone who clones the repository can run git show <hash> to retrieve the original file from any previous commit. Deleting is not enough β€” you must rotate the key immediately and treat it as compromised.

git log β€” the secret survives the deletion
f3a9c12
feat: add OpenAI chat feature
🚨 API key hardcoded here. git show f3a9c12 reveals it instantly.
7e1b4d8
fix: remove hardcoded API key  β† looks safe
🚨 The key is still in the commit above. Deletion only removes it from HEAD, not history.
2c9f0a4
chore: update README
βœ… No secrets here.
0a3e8b1
initial commit

The Defence — Environment Variables

Never Put Secrets in Code

The correct pattern: read secrets from the environment at runtime. Environment variables are key-value pairs set outside your application β€” in a .env file locally, or via your hosting provider's dashboard in production. They never enter your code files, and therefore never enter your git repository.

The correct pattern β€” environment variables
import os

# The secret is read from the environment β€” never written here.
API_KEY = os.environ.get("OPENAI_API_KEY")
DB_PASSWORD = os.environ.get("DB_PASSWORD")

response = requests.get(
    "https://api.openai.com/v1/chat/completions",
    headers={"Authorization": f"Bearer {API_KEY}"}
)
.env file β€” local development only, NEVER committed
# .env  (local file only)
OPENAI_API_KEY=sk-proj-abc123def456ghi789jkl
DB_PASSWORD=VolcPanth#2025!

# This file is listed in .gitignore.
# On Vercel, you set these via Project Settings β†’ Environment Variables.
# They are injected into the runtime environment when your app starts.
.gitignore β€” the guard that keeps secrets out of git
# .gitignore
.env
.env.local
.env.production
*.env

# These patterns tell git to completely ignore any .env files.
# They will never appear in git status, git add, or git log.

The Three-Part Pattern

  • In code: os.environ.get("SECRET_NAME") β€” only the name, never the value
  • Locally: .env file with the values, always listed in .gitignore
  • In production: Set via Vercel dashboard β†’ Project Settings β†’ Environment Variables

Part 3: Security Through Obscurity 8 min

NESA SE-12-07 — Vulnerabilities

What Is It?

Security through obscurity means relying on the secrecy of how your system works as the primary protection β€” not a strong password, not encryption, not server-side checks. Just the hope that attackers don't find out how it's built.

The moment someone discovers the design, all protection is gone. There is no fallback.

You've lived through an example of this. When Volcanic Pantheon had a JavaScript password check, making the GitHub repo private was obscurity: the protection depended on nobody finding the source code. But JavaScript always runs in the browser β€” any visitor can open DevTools β†’ Sources and read every line of it, regardless of whether the repo is private.

Kerckhoffs's Principle (1883)

Cryptographer Auguste Kerckhoffs stated what is still the gold standard of security design:

"A system should be secure even if everything about the system, except the key, is public knowledge."

In modern terms: security should still hold even if an attacker knows exactly how your code works. Only the secret value β€” a key, a password, a token β€” should be what keeps them out, not the design being hidden.

  • Server-side bcrypt satisfies this: an attacker could read your entire source code and still can't log in without the password. The code is not the secret.
  • Client-side localStorage checks do not satisfy this: knowing the code is enough to bypass it. Open DevTools, type localStorage.setItem("authenticated", "true") β€” done.

Challenge β€” Obscurity or Real Security?

Click "Reveal verdict" on each scenario. Think about it first before clicking.

Scenario A

An admin panel sits at /xk92-admin-qp7 instead of /admin. There is no login β€” just knowing the URL grants access.

🚨 Pure obscurity. The unusual URL is the only protection. A web crawler, a log file leak, or a single person sharing the link removes all protection instantly. No real security exists underneath.
Scenario B

A server uses bcrypt password hashing. The source code is publicly available on GitHub.

βœ… Real security. The code being public doesn't help an attacker β€” they still need the correct password. This is Kerckhoffs's principle in action: the design is open; the secret value (the password) is what protects.
Scenario C

A site requires a strong password AND the login form is at an unusual URL not linked from anywhere.

⚠️ Real security + obscurity as a supplement. The password is the real protection. The unusual URL adds a small extra layer. This is fine β€” obscurity on top of real security is acceptable. Obscurity instead of real security is not.
Scenario D

Blake makes the Volcanic Pantheon GitHub repo private. The site still checks passwords in JavaScript using localStorage.

🚨 Pure obscurity. The private repo hides the source from GitHub, but the JavaScript runs in every visitor's browser. DevTools β†’ Sources reveals it instantly. The protection vanishes the moment anyone reads the client-side code β€” which they always can.

Part 4: Packages, Dependencies & Supply Chain Risk 10 min

NESA SE-12-07 — Vulnerabilities

Foundation — What are packages and why does every project use them?

What Is a Package?

Nobody writes everything from scratch. A package (also called a library or module) is code written by someone else that solves a specific problem β€” hashing passwords, making HTTP requests, parsing dates, handling file uploads. You install it and use it instead of building it yourself.

In Python: pip install requests. In JavaScript: npm install express. Your Vercel site for Volcanic Pantheon uses dozens of packages β€” Next.js alone pulls in hundreds of dependencies when installed.

The Dependency Tree

Each package you install often depends on other packages, which depend on others still. This is the dependency tree. A project with 5 direct dependencies might pull in 200+ packages transitively. You are responsible for the security of every single one.

What npm install express actually pulls in
πŸ“¦ your-project
πŸ“¦ express v4.18.2
πŸ“¦ body-parser v1.20.1
πŸ“¦ bytes v3.1.2
πŸ“¦ raw-body v2.5.1
πŸ“¦ iconv-lite v0.4.24
πŸ“¦ accepts v1.3.8
πŸ“¦ path-to-regexp v0.1.7 ⚠ VULNERABILITY
... 24 more packages
πŸ“¦ bcrypt v5.1.0
πŸ“¦ node-pre-gyp v0.13.0

The Vulnerability — Insecure Dependencies

What Goes Wrong

Insecure dependencies means using packages that contain known security vulnerabilities. Your own code might be flawless β€” but if any package in the tree has a flaw, your application inherits it. This is a supply chain attack: instead of attacking your code, the attacker compromises something your code relies on.

Log4Shell (2021) β€” The Most Severe Supply Chain Vulnerability in History

Log4j is a Java logging library used by hundreds of thousands of applications: Minecraft servers, banking systems, government portals, enterprise software.

In December 2021 a critical flaw was found: if Log4j logged a specially crafted string, it would execute arbitrary code on the server. An attacker could type something in a chat box, and if the server logged it, they could run anything they wanted remotely.

None of the developers who wrote those applications had done anything wrong. They installed a widely trusted library. The flaw was inside it.

Hundreds of organisations were compromised. The scramble to patch took weeks. CISA called it "one of the most serious vulnerabilities ever discovered."

The Defence — Audit, Update, Minimise

npm audit scans your dependency tree against public vulnerability databases and reports what needs fixing. Run it regularly β€” especially before deploying.

bash β€” volcanic-pantheon
$ npm audit
found 3 vulnerabilities (1 low, 1 moderate, 1 high)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ high β”‚ Prototype Pollution β”‚
β”‚ Package β”‚ lodash β”‚
β”‚ Version β”‚ 4.17.15 β”‚
β”‚ Fix β”‚ npm audit fix β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ moderateβ”‚ ReDoS in path-to-regexp β”‚
β”‚ Package β”‚ path-to-regexp β”‚
β”‚ Version β”‚ 0.1.7 β”‚
β”‚ Fix β”‚ npm install express@latest β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Run npm audit fix to automatically resolve 2 of 3 vulnerabilities.
$ npm audit fix
added 2 packages, changed 4 packages in 3.2s
2 vulnerabilities fixed. 1 requires manual review.

Defence Checklist

  • Run npm audit regularly β€” especially before any deployment
  • Keep packages updated β€” security patches are released constantly; outdated packages are known targets
  • Minimise dependencies β€” every package added is a potential risk; only include what you genuinely need
  • GitHub Dependabot β€” automatically opens pull requests when a vulnerability is found in your dependency tree

Part 5: Social Engineering & Shoulder Surfing 10 min

NESA SE-12-04 — Safe Data Practices

When Technology Isn't the Weakest Link

Every vulnerability we've covered targets software β€” a query, a DOM insertion, a cookie, a key in code. But even the most technically secure system can be bypassed if the people using it can be manipulated.

Social engineering exploits human psychology β€” trust, urgency, authority, helpfulness, fear β€” rather than code. No software patch fixes a user who hands their password to someone posing as IT support.

You've already experienced a real social engineering attack. When a friend saw your project name on your screen and searched for it, that was shoulder surfing β€” an attacker observing physical information you didn't intend to share. It caused you to rename the project, move to Vercel, and make the repo private. That's a genuine real-world social engineering incident affecting your own work.

Attack Types

Attack Mechanism Real Example
Shoulder surfing Watching someone's screen or keyboard to steal credentials or information Friend sees project name on screen; searches for the site
Phishing Fake emails or sites impersonating trusted entities to steal credentials Fake GitHub security alert asking you to "verify" your account
Pretexting Fabricating a scenario to extract information or access "Hi, I'm from IT β€” we need your login urgently to fix an issue"
Baiting Leaving infected USB drives or devices for victims to find USB stick labelled "Salary Information 2025" in a company car park
Tailgating Physically following an authorised person through a secured door Walking in behind someone who badge-swiped through a server room door

Recognising a Phishing Email β€” Interactive Example

The email below has 5 red flags. Click the numbered circles in the email to jump to the explanation, or click the flags in the legend below to reveal each one.

Defences

  • Education β€” the single most effective control. Knowing these attacks exist and what to look for makes you dramatically harder to fool. You knowing this now matters.
  • Verify through a separate channel β€” if you receive a suspicious message, go directly to the real site in a new tab. Never use contact details from the suspicious message itself.
  • Multi-factor authentication (MFA) β€” limits damage when credentials are stolen. Even if phishing captures your password, the attacker still needs the second factor.
  • Least-privilege access β€” if social engineering succeeds against one person, they only gain what that person has access to. Smaller permissions = smaller blast radius.
  • Physical awareness β€” be conscious of who can see your screen in public. What project names are visible in your taskbar right now?

Part 6: Knowledge Check 8 min

HSC-Style Questions — Answer Before Looking

  • Q1 (2 marks): A developer commits an API key to a public GitHub repository, immediately realises the mistake, and deletes the file in the next commit. Explain why this does not eliminate the risk.
  • Q2 (3 marks): Describe security through obscurity and explain, using Kerckhoffs's principle, why it is not an adequate primary defence. Give one concrete example.
  • Q3 (2 marks): What is a supply chain attack? Use a real or realistic example in your answer.
  • Q4 (2 marks): Identify two social engineering techniques and describe one defence that reduces the effectiveness of both.

Model Answers (Click to Reveal)

Q1: Git History

Deleting a file in a new commit does not remove it from version control history. Git retains every previous commit. An attacker who clones the repository can run git log followed by git show <hash> to retrieve the file from the commit where the key was present. To truly remove a secret from history, the developer must rewrite git history using tools such as BFG Repo-Cleaner β€” and even then, the key must be immediately rotated and treated as compromised, since anyone who cloned the repo before the rewrite still has the original history.

Q2: Security Through Obscurity & Kerckhoffs's Principle

Security through obscurity means relying on the secrecy of a system's design as its primary protection, rather than on genuine security controls such as encryption or authentication.

Kerckhoffs's principle states that a system should be secure even if everything about it β€” except the key β€” is public knowledge. Security through obscurity violates this principle: if the design is the secret, discovering the design instantly removes all protection with no fallback.

Example: A JavaScript password check in a private GitHub repository. Making the repo private hides the source from GitHub, but the JavaScript still runs in every visitor's browser β€” opening DevTools always reveals it. Once the design is known, the check is bypassed immediately. A server-side bcrypt authentication would remain secure even with the source code fully public.

Q3: Supply Chain Attack

A supply chain attack targets software that an application depends on rather than the application's own code. The attacker compromises a library, package, or tool used by many developers, and the vulnerability propagates to all applications that depend on it.

Example: Log4Shell (CVE-2021-44228, 2021). Log4j is a widely used Java logging library. A critical flaw allowed remote code execution by logging a specially crafted string β€” attackers could trigger it by submitting input to any form or field that the application logged. Applications across banking, gaming, and government were vulnerable through no fault of their own code, simply because they used a trusted dependency.

Q4: Social Engineering Defences

Techniques: Phishing (fake emails or websites impersonating trusted entities to steal credentials) and pretexting (fabricating a scenario β€” e.g., posing as IT support β€” to manipulate a target into revealing information or granting access).

Shared defence: User education. Both attacks rely on the target not recognising that they are being manipulated. Training users to identify warning signs β€” unsolicited urgency, requests for credentials, mismatched domains, unexpected contact from authority figures β€” significantly reduces the success rate of both techniques. A user who knows these attacks exist is far harder to fool.

(Multi-factor authentication also applies to both: even if phishing or pretexting successfully captures a password, the attacker still requires the second factor.)

What You've Learned Today

  • Hardcoded Secrets β€” Sensitive values in source code travel everywhere the code travels, and git history preserves deleted secrets forever. Fix: environment variables read at runtime, .env in .gitignore.
  • Security Through Obscurity β€” Relying on design secrecy as primary protection violates Kerckhoffs's principle. Use controls that remain secure even when the design is public.
  • Insecure Dependencies β€” A vulnerability in any package in your dependency tree becomes your vulnerability. Fix: npm audit, keep packages updated, minimise what you install.
  • Social Engineering β€” Attacks target people, not systems. Phishing exploits urgency; shoulder surfing exploits physical proximity. Fix: education, MFA, verification through separate channels.

Curriculum Progress

  • Year 12 Secure Software β€” vulnerabilities section: complete across Lessons 7–10
  • HSC Outcomes SE-12-04 and SE-12-07: full coverage
  • Next lesson: how to test for these vulnerabilities β€” SAST, DAST, and penetration testing

Homework Before Next Lesson

Part A — Code Review

For each snippet: (a) name the vulnerability, (b) explain what an attacker could do with it, and (c) write the corrected version.

Snippet 1
STRIPE_KEY = "sk_live_4eC39HqLyjWDarjtT7jkd782"

def process_payment(amount, card_token):
    stripe.api_key = STRIPE_KEY
    return stripe.Charge.create(amount=amount, source=card_token)
Snippet 2
// Admin panel β€” no login required.
// The URL is the only protection.
app.get('/secret-admin-xk92', (req, res) => {
    res.sendFile('admin.html');
});

Part B — Phishing Awareness

You receive this SMS: "Your Vercel deployment failed due to a billing issue. Verify your card now to prevent your site going offline: vercel-billing-verify.net/confirm"

  1. Identify three red flags in this message.
  2. What could an attacker do with information entered on that site?
  3. What should you do instead of clicking the link?
Check your answer

Red flags: (1) The URL is vercel-billing-verify.net β€” a lookalike domain, not vercel.com. (2) Urgency: threat of the site going offline. (3) Vercel communicates via email and the dashboard, not unsolicited SMS.

What an attacker could do: The fake site likely mimics the Vercel login or payment page. Entering credentials gives the attacker account access β€” they could deploy malicious code, modify environment variables to extract secrets, or access private repositories. Card details enable financial fraud.

What to do: Do not click the link. Open vercel.com directly in a new tab. Log in and check the billing and deployments sections. Any real issue will be visible there.

← Back to Blake's Learning Hub