SESSION 04 / 06

Press F12
and it is all visible

F12 · 6 defenses · Security audit · account.md

Jee Jun Young

Business major → Journalism · Overseas sales → Software development
iOS · Android · Frontend About 5½ years (sixth year)
Developed iOS/macOS apps for an enterprise collaboration tool
Since 2026 Solo web and server development and commercialization through vibe coding

PART 1 — Recap of session 3

Today, I have
something scary to talk about.

WHY WEB IS WILD

The web and servers are the wild

Security specialists scare me too. I am not a security expert.

Mobile vs. web — developers are responsible for different areas

iOS · Android
Apple and Google block half of it for you

Sandbox · Code Signing · ATS · Keychain · App-store review — basic security at the OS and platform level

Web · Servers
It is all the developer’s responsibility

HTTPS · CORS · CSRF · XSS · SQL Injection · DDoS · Server OS · Authentication and authorization — all up to you

The web is the field AI has trained on most

AI
It builds the average case very well

Login, message boards, dashboards — the average of the training distribution. Strong at making features work.

Hackers · Bots
They attack outside the average case

Edge cases, abnormal input, unusual conditions. The academic term: adversarial robustness

Take care of it, and it runs well. Neglect it, and it fails.
Today’s 6 defenses are the minimum to take care of.

EDGE CASE · Payments

A prime example far outside the average: adding payments

“Done in 5 minutes? It worked when I followed the tutorial?”

Try it. With no sales, you may never notice, close the business and bury it.
When sales grow and you become a target — that is when you find out.

Payments are the most complex feature, with countless procedures and branches stacked layer upon layer.
Those layers must not contradict each other. Edge cases barely covered by average AI code multiply.

Idempotency Atomicity Concurrency Webhook verification Amount verification

Why is it scary? Two familiar examples

• iOS in-app purchases — the field that used to torment game companies. Apple’s 30% fee, auto-renewals, refunds, receipt verification…
• Small-business customer support — payment incidents draw customer fury directly. “Where is my money?” Abuse, a flood of 1-star reviews, reputation destroyed in a month.

What concerns me as the instructor

Payments — my biggest concern right now

I have shown you my novel-publishing service a few times in class, right?

This is what I think about most right now —
defending the attack points in payments.

F12 · DEVTOOLS

F12 is the browser’s X-ray.

In Chrome: on any page, right-click → Inspect.
Or ask Claude: “Am I using Windows or Mac? How do I open the web developer tools?”

What the Network tab shows

API endpoints, request contents, response contents
Which AI model is used, environment variables, localStorage, cookies
All publicly visible.

It is normal to see bones in a hospital X-ray.
Checking things on your own computer is not hacking either.

The issue is that anyone can open it.
The browser does not distinguish developers from hackers.

TWO RISKS

Two reasons why visibility through F12 is dangerous

Risk ①
Your users get robbed
Emails, payment details and personal information exposed.
Directly tied to security and money.
I will show 3 incidents shortly.
Risk ②
You get robbed
AI models, prompts, logic
Your core recipe is completely exposed.
A competitor copies it over a weekend.

F12 concerns protecting users and, at the same time,
protecting your ideas.

ANALOGY

Real security means “Can they take it?”

The bedroom-drawer analogy

Taking your diary out in your own room is not an incident.
The real incident is letting a thief break the window and steal it.

An amusement-park wristband — where you keep it matters

A. A shared table
localStorage
Dumping keys and credentials that must not be exposed here lets a thief pick them up immediately
B. A bank vault
HttpOnly Cookie
Visible by X-ray, but cannot be taken out

The same wristband is different depending on where you put it.

The “thief” is an XSS attacker

Someone has planted malicious JavaScript on the page (Cross-Site Scripting).
JavaScript on the same domain can read all of localStorage → the malicious script steals the token.
HttpOnly cookies are invisible to JavaScript → it cannot steal them. HttpOnly’s job: prevent token theft even when XSS occurs.

PART 2

A 10-second attack
3 real incidents

A hacker needs less than
10 seconds to break into a solo developer’s site.

INCIDENT 01

EnrichLead — attacked for 2 days, shut down in 1 week

The problem: all 4 basic defenses were missing

A B2B lead SaaS whose founder boasted, “I did not write a single line.”
API keys exposed in the frontend, no authentication, an unprotected database, no rate limiting.

Attack path

Browser console bypassed payment → paid features used for free → API quota exhausted.
Tried fixing it with Cursor → “It kept breaking other things” → gave up and shut down.

KEY TYPES · Know the two types

Public keys
Can be embedded in apps and browsers
Firebase apiKey · Google Maps · Stripe pk_* · Supabase anon
→ But always enable limits and policies (Security Rules, App Check, Restrictions).
Secret keys
Never in the client
Anthropic sk-ant-* · OpenAI sk-* · Stripe sk_* · Supabase service_role
→ Always backend environment variables.

Self-check: “If this key leaks, can anyone call the service, spend money or gain privileges?” YES → secret. NO → public.

Lesson: keep secret keys somewhere safe.
For web/server systems, isolate them in backend environment variables. iOS/Android apps must call through your own backend. Public keys can be embedded, but policies are mandatory.

INCIDENT 02

Moltbook — 1.5 million API keys leaked

How it happened: two mistakes combined

An AI-agent social platform whose founder, Matt Schlicht, declared, “I did not write a single line.”
Built on Supabase: RLS off + a privileged key exposed in client JavaScript.
→ The anon key itself can be public. The incident came from combining disabled RLS with an exposed secret key.

Result: 1.5 million API keys, 35,000 emails and all private agent conversations leaked.
Security firm Wiz Research published its investigation.

Lesson: always enable Supabase RLS and Firebase Security Rules.
Have Claude check every time.

INCIDENT 03

Tea app — 72,000 images and 1.1 million messages

First leak (July 2025)

A women-only app collecting driver’s licenses and selfies at signup.
Firebase Storage permissions were left open to everyone.
72,000 images leaked, including about 13,000 selfies and driver’s-license images.

Second leak (days later)

Another 1.1 million private messages leaked.
Including extremely sensitive conversations about abortion and affairs.

Lesson: if you have file uploads,
always check Storage permissions.

KBS Chang, episode 540 · Two segments to watch

The program shows only the finished result

“My Perfect Secretary: The Age of AI Agents” · youtu.be/QQJpyIO014A

Case ① · Opening segment — the documentary’s protagonist

Security-startup CEO · Lives in Bali · Works 30 minutes a day · Only approves agent results

Four things we can only guess about how that person got there:

Q1
How much research and development?
Q2
How much has this person learned?
Q3
How much trial and error?
Q4
Tens of millions of won in tokens per month?

(For reference, some companies pay over 20 million won a month for Palantir Enterprise.)

Case ② · Minutes 28–32

A hotel-booking agent was told to “spend only 500,000 won” and spent 760,000 won.

A controlled attack experiment by KAIST researchers and KBS staff. The scenario uses hostile code and prompts planted on an external web page to misdirect the agent. Not an actual victim.

My background: magazine reporter (introduced on day one). How media works is the result of editorial intent.

Watch at home and check two things:
① The CEO’s effort, study, trial and error, and costs — are they shown?
② The attack mechanism (attention, tool calling, judgment, IDPI) — is it clearly explained?

If not, it was cut in editing. That is the nature of media.

The decisive question:
“Is the service I am building ready to defend against that attack?”

PART 3

Basic defenses:
6 of them

No need to memorize them. Take a photo.
The key is adding one line to Claude: “Include this too.”

TODAY · 6 BASIC DEFENSES

The 6 basic defenses at a glance

① Database
Enable RLS (Row Level Security)

Mark who owns each database row → users read and write only their own rows.
Example: “Only I can see my posts, not other people’s.”
Supabase/Firebase default: OFF — without enabling it, anyone can access every row.

② Key management
Do not hardcode API keys

A hardcoded key is exposed worldwide the moment it reaches GitHub. Separate it into .env.

③ Environment-variable exposure
Watch out for NEXT_PUBLIC_

Keys prefixed with NEXT_PUBLIC_, VITE_ or REACT_APP_ are embedded in the bundle and exposed to the browser.

④ Where AI calls run
Call AI from the server

Embedding OpenAI/Anthropic keys in the client (browser/app) to make calls gets them stolen immediately. Use a BFF/API Proxy pattern.

⑤ Build output
Disable source maps

If production exposes .map files, obfuscated code can be restored to the original. productionBrowserSourceMaps: false

⑥ Git hygiene
Put .env in .gitignore

If you accidentally commit .env, bots harvest the keys automatically within 30 minutes of pushing.

We will go through these six one by one.

IF YOU SKIP — WORST CASE

What happens if you skip all 6?

💰 Money
“Losing tens of millions is easy”

An exposed API key → bots collect it within 30 minutes → OpenAI/AWS bills explode.
Tens to hundreds of millions of won in one month are possible.

📋 Legal liability
“Customer data stolen — you get sued”

Violating Korea’s Personal Information Protection Act → penalty of up to 3% of revenue plus damages per victim.
A class action can bankrupt even the individual owner of a small business.

🔒 Hostage
“Database breached — data held hostage”

Ransomware encrypts the database → demands a Bitcoin ransom.
Without backups, the business ends. Average global ransom: $800,000–$1.5 million.

📉 Reputation
“Reputation collapses → revenue hits zero”

A flood of 1-star reviews and public shaming on X (Twitter) → trust cannot be restored within a month.
“That site had a payment incident” — one line can mean zero revenue.

All four can happen if even one of the 6 defenses is missing.
Ruin. No exaggeration. Real cases appear every week.

DEFENSE 01
Enable Supabase RLS and Firebase Security Rules
If a dashboard warning ⚠️ appears, enable them immediately.
# Add one line for Claude “Create the table, and create the RLS policies too.”

Check each table’s RLS policies and actual access permissions together.

RLS, simply

What is RLS? Apartment mailboxes

Analogy

On the ground floor are mailboxes for 100 apartments.
“Only I can open my own mailbox” — that is normal.
→ RLS enabled = normal

What if you do not enable it?

Any resident can open all 100 mailboxes.
They can read neighbors’ bank statements, card bills and registered mail.
→ Supabase/Firebase default: OFF. Without enabling it, anyone can read and modify every user’s data.

RLS = “Only the owner can open this data row.”
In one line: put a lock on each mailbox.

DEFENSE 02
Do not hardcode API keys
Use a .env file and the hosting dashboard’s environment variables.
# .env (do not commit to Git) OPENAI_API_KEY=sk-... ANTHROPIC_API_KEY=sk-ant-... # Use a variable in code process.env.OPENAI_API_KEY

In Vercel or Netlify, enter them in the dashboard’s environment-variable fields.

API keys, simply

What is a secret API key? A hotel master key

Analogy (secret keys only)

A hotel employee’s master key opens every room.
OpenAI, Anthropic and AWS secret keys work the same way. “With this key, you can use that company’s services however you like.”
→ Usage is billed to the key owner: you. Public keys are different; see slide S10.

What if you put it in the code?

It is like hanging the hotel master key unlocked at the front entrance.
Anyone passing by can take it, open every room and empty the minibars and safes.
→ Once a key reaches GitHub, bots collect it within 30 minutes → OpenAI bills explode, reaching tens to hundreds of millions of won in a month.

Do not put it in the code. Separate it into a file called .env.
Never commit .env to Git (next slide).

DEFENSE 03
Watch the NEXT_PUBLIC_ prefix
This prefix means “public to the world.”
❌ Dangerous
NEXT_PUBLIC_OPENAI_KEY
Exposed directly in the browser
✓ Safe
OPENAI_KEY
Exists only on the server

The EnrichLead incident was exactly this mistake.

Other frameworks follow the same rule: VITE_ (Vite), REACT_APP_ (CRA). Different names, same client exposure.

Public keys can use the prefix

Public keys such as Firebase apiKey, Stripe pk_* and Supabase anon can use NEXT_PUBLIC_* or VITE_*. They are intended to be public.
→ Never use these prefixes for secret keys. See S10.

NEXT_PUBLIC_, simply

What is NEXT_PUBLIC_? Shop sign vs. owner’s safe

Analogy

A shop has two kinds of writing.
The sign: any passerby can read it (phone, address, menu).
Inside the owner’s safe: even staff cannot see it (cash, seals, bankbooks).
→ A key prefixed with NEXT_PUBLIC_ is writing on the sign. The build sends it straight to the browser.

What if you add it to a secret key by mistake?

Like writing the safe’s combination on the shop sign.
Add NEXT_PUBLIC_ to a secret key, such as OpenAI sk-* or Supabase service_role, and one F12 press puts it in a thief’s hands.
→ VITE_ and REACT_APP_ work the same way: the same trap in other frameworks.

Rule: the prefix means “this reaches the client”.
→ Only public keys belong here (Firebase apiKey, Supabase anon, Stripe pk_*). Never secret keys: that would put the safe combination on the sign.

DEFENSE 04
Call AI from the server
BFF proxy pattern — your server relays the request.
Browser → Your server (API Route) → OpenAI API ↑ Use the API key only here

Always tell Claude: “Call it from a server-side API Route.”

PLATFORM · Apply it on each platform

Web
Next.js · Vite · Nuxt
→ Call only from a server-side API Route (Next.js /api/*; for Vite, a separate Express, Hono or Vercel Functions backend). Keep keys in backend environment variables.
iOS
Swift · SwiftUI
Do not embed keys in the app (IPA decompilation extracts them). Call through your own backend. Store only user tokens in Keychain.
Android
Kotlin · Jetpack
Do not embed keys in the app (APK decompilation extracts them). Call through your own backend. Store only user tokens in Keystore.

→ Shared principle: secret keys (OpenAI, Anthropic, Stripe `sk_*`, Supabase service_role, etc.) must be used only in your own backend. User authentication tokens (JWT/OAuth) belong in the OS Keychain/Keystore. These three are different types.

A common confusion: “But Firebase says to put the key in Info.plist?”

Correct. Firebase apiKey is a public key with no privileges by itself, so it can be embedded in the app.
The real defenses are Firebase Security Rules and App Check. Google Maps keys, Stripe `pk_*` and Supabase `anon` are similar.

→ Recall the public vs. secret key table in S10. Secrets stay in the backend; public keys can go in apps, but policies must be enabled.

BFF, simply

What is BFF? Customer / employee / owner

Analogy: a restaurant

Customer = user (browser)
Employee = your server (BFF, Backend For Frontend)
Owner = external API (OpenAI, bank, payments)
→ Customers must not enter the owner’s office and touch the safe. The employee takes their request to the owner.

What if the customer meets the owner directly?

The customer learns the safe’s combination (API key).
Then they return daily pretending to be another customer and empty the safe.
→ Calling OpenAI/banks directly from the client exposes API keys. Bots collect them and bills explode.

Rule: customers meet only the employee. The employee passes the request to the owner.
So AI, payment and database calls must go through your server (BFF), never the client.

DEFENSE 05
Disable production source maps
If enabled, F12 shows your original code, including comments.

What is a source map?

Your code (TS, JSX, modern JS) → the build tool runs a four-stage conversion, including compression, translation and bundling → sends it to the browser. People cannot read the transformed code.

For debugging, the build separately creates an original-to-compressed-code translation table. That is the .map file: the source map.

Analogy: a translation table for the English edition of a Korean book, used to locate the Korean original when the English edition has a typo.

The same function: original vs. built output (what a person wrote vs. what reaches the browser)

// Original function calculatePriceWithVAT( basePrice, additionalFee) { // Apply 10% VAT return basePrice*1.1+additionalFee }
// After build (minified) function n(a,b){return a*1.1+b} // One line, single-letter variables. // All comments removed.

Deploy with source maps enabled and F12 shows the left-hand original as-is: what functions do, business logic and comment notes.

DEFENSE 05 · Settings and reasons for exposure

Source maps: one-line configuration, and what about other companies?

// next.config.js — one line module.exports = { productionBrowserSourceMaps: false } // For Vite: build.sourcemap: false

Cases where source maps are public

①

Build settings were not checked

②

Client-code publication was allowed

③

Production errors are traced against original code

④

Code was published as open source

⑤

Core logic is kept on the server

Check whether your project exposes original code, comments or core logic.

Ask Claude: “Check whether source maps are exposed in this project’s production build.”

ADVANCED · Advanced option

hidden-source-map: the standard pattern for security and debugging

Choose between two options

① Disable completely (`sourcemap: false`): safest, but production errors become harder to trace.
② hidden-source-map: generate maps without adding a sourceMappingURL comment. Ordinary users do not see them in F12.

How hidden-source-map works

Do not include generated .map files in the server deployment; upload them separately to an error-tracking service such as Sentry or Datadog.
→ Production errors can be traced to the original line in Sentry, but not viewed through F12.

Options by framework

Next.js — productionBrowserSourceMaps: false + Sentry integration
Vite — build.sourcemap: 'hidden'
Webpack — devtool: 'hidden-source-map'
CRA — GENERATE_SOURCEMAP=false (CRA does not support hidden maps)

In one line: fully disabled is safest; hidden combines security and debugging.
Move to hidden as your service grows and you start using Sentry or Datadog.

Source maps, simply

What is a source map? A building blueprint

Analogy

Looking only at a finished building, ordinary people cannot locate vents, secret passages or safes.
A blueprint shows where everything is.
→ A source map pairs compressed code with original code. With it, F12 shows the original as-is.

What if you publish the blueprint?

The thief learns every vent, secret passage and safe location.
The exterior is unchanged, but the ways in become countless.
→ Exposed production .map files reveal business logic, security checks and comments. Weak points are immediately visible.

Rule: once the building is finished, put the blueprints in the company safe. Do not publish them.
One line: productionBrowserSourceMaps: false.

DEFENSE 06
Add .env to .gitignore
Once it reaches Git, hacker bots detect it within a minute.
# .gitignore .env .env.local .env.*.local

If already committed by mistake, it remains in Git history.
Replace the key immediately.

Git, .gitignore and .env, simply

What is Git? A diary backup

Analogy

Git = automatic diary backup (photographing and saving it to the cloud daily)
.env = secret diary (passwords, bank codes, gossip about someone)
.gitignore = the “do not back this up” list
→ Git automatically uploads all files to the cloud. Put the secret diary in .gitignore to keep it out.

What if it is not in .gitignore?

Even the secret diary gets backed up to the cloud. And it stays in history forever. Once a password is uploaded, replace the key immediately.
→ An accidental .env commit to GitHub lets bots harvest keys within 30 minutes. AWS/OpenAI bills explode. Deleting it afterward does not remove it from history.

Rule: always add .env, .env.local and .env.*.local to .gitignore.
The first thing to do in a new project.

6 DEFENSES — CHECKLIST

01
Enable RLS
02
Do not hardcode API keys
03
Watch NEXT_PUBLIC_
04
Call AI from the server
05
Disable source maps
06
.env in .gitignore

Use these six checks
to inspect exposed keys, database permissions and file access.

KEY MANAGEMENT · Putting it together

The many keys powering my service — how do I classify and manage them?

One service: Supabase anon, Firebase apiKey, OpenAI sk-, Stripe pk_/sk_, Google Maps, Anthropic sk-ant-… Having 5–10 keys is common.

① Can be written in relatively public places
Public keys

Firebase apiKey · Google Maps · Stripe pk_* · Supabase anon
→ Identification only. No privileges or money by themselves.

② Must never be public
Secret keys

Anthropic sk-ant-* · OpenAI sk-* · Stripe sk_* · Supabase service_role
→ Backend environment variables only.

Quick self-check: “If it is stolen, do I get billed? Can they access my database?”

YES → secret. Backend only.  |  NO → public. Client is fine, but additional defenses are required.

Keeping public keys safe: additional defenses

① Policies (RLS / Security Rules)

“This user can access only their own data,” per database row or document. Supabase RLS, Firebase Security Rules.

② Domain and bundle restrictions

Application Restrictions: a Google Maps key can be called only from your domain or bundle ID. Requests elsewhere are rejected.

③ App Check / origin verification

Firebase App Check verifies that calls really come from your app. Blocks bots and scraping.

And always keep secret keys separate in .env, listed in .gitignore, and only in backend environment variables.

In one line: public key + policies = safe. Public key without policies = disaster.
Putting in a key does not finish security. Enabling policies is half the work.

☕

10-minute break

When we return,
we will talk about “Claude forgets.”

PART 4

Claude forgets
+ Use AI to monitor AI

TODAY · Two more of the 10 principles

In the second half, we add 2 more of the 10 principles.

07
The fundamentals are weapons for pushing back
08
Build it yourself to see the limits

We will unpack these two in the second half.

First, Claude’s “I recorded it” lie, and the account.md solution.

PART 4 — CLAUDE FORGETS

“I recorded it” — do not believe it.

My actual experience

I told Claude, “Write this down.”
It replied, “Yes, I recorded it.”
I asked in the next session: it did not know. Quite often, it never recorded anything.

Claude starts from scratch every session.
It has no memory. We covered that in session 3.

An even worse case

Sometimes, even within the same session, it cannot remember what you said 2 hours ago.
→ As context grows, earlier content becomes blurry. Exactly the Context Rot from session 3.

When Claude says “I recorded it,” always check.
Write down important things yourself.

Solution: a human writes the notes

account.md (add to .gitignore)

Where keys were issued, cloud-account emails, infrastructure settings, container names
Never include passwords

# Security section to add to CLAUDE.md ## Security rules - Never commit .env to Git - Use API keys only on the server side - Keep RLS enabled on Supabase tables - Tell me immediately if these rules are violated

When rules grow, move them to a separate file

When security rules get long, move them to SECURITY.md and leave only a reference in CLAUDE.md.
→ The canonical-source/reference pattern from session 3: keep CLAUDE.md short and separate details by file.

A practical security use of the canonical-source concept from session 3. Claude reads and recognizes these rules each session.

PART 5

Have AI run
a security audit

Session 2 principles: document, monitor, push.
For security, monitoring is central.

AUDIT PROMPT

Security-audit prompt: copy and paste this

Audit this entire project for security. Check: 1. Whether any Supabase tables have RLS disabled / Firebase Security Rules are empty 2. Whether .env was committed to Git 3. Whether secret keys (sk-/sk_/service_role) are hardcoded in client code 4. Whether sensitive values have the NEXT_PUBLIC_ prefix 5. Whether paid AI APIs are called from the client instead of the server 6. Whether source maps are exposed in the production build

Send Claude’s audit results to Gemini and Codex for another review.
When the same AI audits its own code, it says, “No problems.” Gemini often comments on the report and suggests useful next steps.
The point is cross-checking.

This is not the end

Web and backend systems have an enormous number of things to defend against.
These 6 are a starting point. OWASP Top 10, token storage, CSP, CORS, rate limits, SQL injection, CSRF, SSRF, race conditions — the list goes on.
→ Today’s 6 are the ones vibe coders most often miss.

REAL · External check just before class

One step further: results from an outside perspective

S36 is for static analysis of your own code. This is different: external runtime checks from just one page (token storage, response headers, exposed paths).

Target: a Korean AI-writing SaaS · Tool: Claude Chrome MCP · Instruction: just “Run a security audit” · Anonymized

① Authentication token: stored in localStorage

Key *_token, JWT format, 120 characters.
→ A core anti-pattern from session 4. Anyone can see the token with one F12 press.

② Decoded token: long-lived, 24 hours

HS256; only sub and exp in the payload (no iat, jti, iss or aud); expires in +24 hours.
→ Standard access tokens last 15 minutes to 1 hour. 24 hours without jti means no forced revocation after theft and unrestricted use for 24 hours.

③ Security response headers: 5 missing

CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy and Permissions-Policy: all missing.
→ Only HSTS is enabled. A CSP line could have blocked inline XSS scripts — zero layers of defense.

④ Many third parties + no CSP = more supply-chain attack surface

Loads GTM, GA and multiple external CDNs. No CSP → if one domain is compromised, malicious code can reach all users of the site.

A live, paying service operating with almost all the anti-patterns from session 4.
It simply has not been breached yet; it is very easy to breach.

PRECISELY · To be precise

① Using localStorage for tokens alone: open to debate

Review token storage together with CSP and XSS defenses.

② Combination (localStorage + no CSP + 24h + no jti) — items to check together

Check CSP, token expiry and protections against token reuse together.

③ In one line

Never put sensitive values (authentication, payments, personal identifiers) in localStorage.
Dark mode, language and UI state are fine. Secrets are not.

④ This service

Closer to the latter combination (②).
The criticism is not about localStorage alone: the combination makes it dangerous.

SO — At least the minimum

This is why at least basic security matters

First: not unable, just undone

They built a clean service with Vite, React and Vercel. They are clearly smart.
They skipped one 5-minute task: putting authentication tokens in HttpOnly cookies.

Second: even trillion-won companies skip it

EnrichLead, Moltbook, Tea — all were taking payments.
They skipped the minimum, and one incident shut a company down in a week (EnrichLead).

Third: you face the same threats

The moment you add payments and accept users through vibe coding, one F12 press shows everything.

The minimum: 6 defenses + account.md + a security-audit prompt.
All three are mandatory. One unrecoverable incident is enough to end it.

One last thing

My entire instruction was “Run a security audit” in Korean.
Claude found this much from that one line.

So what if someone skilled at attacks targeted the same site? What then?

TEST

Testing: machines monitor machines

Unit tests, E2E tests, UI tests — no need to memorize these now.
Simply put, they are automated verification programs.

Traditional development: developers write them.
Vibe coding: ask Claude to do it.

One line: “Create test files for this feature too.”

MARTIN FOWLER · 1999

“Any fool
can write code that a computer can understand.
Good programmers
write code that humans can understand.”

— Any fool can write code that a computer can understand.
Good programmers write code that humans can understand.
『Refactoring: Improving the Design of Existing Code』 (1999)

That was said 27 years ago.

Back to session 1: “Books matter / do not dismiss experts / Anthropic learned from books too.”
This man is an example. A god of the software industry.

Of course there are also Dijkstra of Dijkstra’s algorithm and Liskov of the Liskov substitution principle.
More precisely, he is a god of enterprise practice, not theory.
Different fields, but yes: a god you could not catch even after learning to code for a thousand years.

2023–2025 — still active

martinfowler.com · Runs the Exploring Generative AI series.
The author of a book from 27 years ago still writes about coding in the AI age.

In other words, your Claude has probably learned from all of his writing too.

Twist that for the vibe-coding era:

“Any AI can write code that a computer understands.
A good user writes code and documentation that both AI and humans understand.”

That starts with fundamentals,
and technical terms developers think about: architecture, design patterns, code complexity.

PRINCIPLE 07
Fundamentals are not disposable knowledge; they are tools for pushing AI
You are not learning this to write code yourself. You learn it to push AI.

F12, RLS, NEXT_PUBLIC_, source maps, BFF proxies, permission checks —
without these words, you cannot challenge AI’s code.

When Claude says “It is safe,” ask:
“Did you enable RLS? Is this key exposed to the client?”

The terms in session 5 will become tools too:
Clean Architecture, MVVM, FSD, idempotency, atomicity, design patterns…

PRINCIPLE 08
Build it yourself to see the limits
Only deploying and pressing F12 develops a sense for security.

If you did the homework for sessions 2 and 3,
press F12 today and feel: “Oh, all of this is visible.”

If you have never deployed, you know it only in theory.
Only seeing it yourself builds that sense.

PRINCIPLE 08 · Practice

The quickest way to build intuition: refine images

Simpler than code. Anyone can try.

Try image-generation AI for illustrations, landscapes, oils and watercolors.

My example: refined 100+ images since the Gemini app first launched. Made the emblem for my motorcycle group myself.

Comparing AI: only hands-on refinement teaches you

Images
Nano Banana (Gemini) ↔ Duct Tape (OpenAI)

“Could Duct Tape beat Nano Banana?” Compare them yourself.

Code
Codex ↔ Claude (developers weigh them too)

“Switch to Codex? Use Codex only for reviews? Let Claude do the work?”

My analogy after using both models

Gemini
A bohemian who graduated top of philosophy and art school

Strong at brainstorming. Long writing reveals overreaching leaps.

Claude
A lawyer who graduated top of law school

Strong at specifics, narrative structure and logical consistency. Smart, but a shirker: needs constant pressure.

Methods for pushing AI: actively studied by developers

• Harness engineering: the broad umbrella. How to design the AI’s working environment.
• Agents: autonomous units within it. AI selects tools, plans and executes independently (Claude Code, Cursor Composer).

Part of the same research direction. More in session 6.

10 PRINCIPLES — All 10 complete

01
Beware of hype
02
Machines are lazy, and they lie
03
Document · Watch · Push
04
Do not try to study it all yourself
05
Use machines to watch machines
06
Delegate instead of studying
07
The fundamentals are weapons for pushing back
08
Build it yourself to see the limits
09
If verification takes longer than the work, you have failed
10
You are the advertiser; the machine is the agency

We have covered all 10 principles.
They form the backbone of this 6-session course.

PART 6 — HOMEWORK

Today’s homework

TASK 1
Press F12 on your own site
Network, Sources and Application tabs. See what is publicly exposed.
TASK 2
Have Claude run a security audit
Copy and paste the 6-item prompt from S22.
TASK 3
account.md + CLAUDE.md security section
Add today’s 6 defenses directly to CLAUDE.md.

SESSION 04 / 06

Thank you
for your work today.

Next: session 5.
“Just handle it” does not work: the power of technical vocabulary.

Open-chat QR code

Questions go to the KakaoTalk open chat.