ITS8 Cloud Services ยท Security

How We Secured the Project

Seven security layers โ€” from the moment a user types the URL to the data stored in the database. Each one explained simply.

HTTPS / TLSDNS & WAFSecurity HeadersSecrets ManagementRow Level SecurityCI/CD SafetyMonitoring
๐Ÿ”’
Layer 1

HTTPS & Transport Security

Every byte of data between the user and the site is encrypted.

When you visit a website that starts with "https://" the padlock means your connection is encrypted. No one in the middle (your ISP, a hacker on public Wi-Fi) can read what's being sent. Without it, passwords and data travel as plain text.

โœ“
TLS Certificate โ€” Cloudflare Universal SSL โ€” free, auto-renewing certificate applied to tradingwithhak.com. Issued in minutes, no manual renewal.
โœ“
HTTPS Redirect โ€” Cloudflare automatically redirects all http:// traffic to https://. Users can never accidentally land on an unencrypted version.
โœ“
HSTS Header โ€” HTTP Strict Transport Security tells browsers: "only ever connect to this site over HTTPS, even if a link says HTTP." Prevents downgrade attacks.
โœ“
TLS 1.2+ โ€” Cloudflare enforces TLS 1.2 minimum. Older, broken versions (SSLv3, TLS 1.0) are blocked.
Covers: DNS, Security & Monitoring โ€” 10 pts
๐ŸŒ
Layer 2

DNS Security

Controlling how the domain name resolves โ€” and protecting it.

DNS is the phone book of the internet. When someone types tradingwithhak.com, DNS translates it to an IP address. If an attacker can tamper with DNS records, they can redirect your visitors to a fake site. Securing DNS means making sure only authorized people can change those records.

โœ“
Cloudflare DNS โ€” Cloudflare manages all DNS records for tradingwithhak.com. Changes require login with 2FA โ€” no one else can modify them.
โœ“
Proxied Records โ€” All DNS records are "proxied" through Cloudflare. The real server IP is never exposed publicly โ€” attackers cannot target the origin directly.
โœ“
DDoS Protection โ€” Cloudflare's network absorbs volumetric attacks (millions of fake requests) before they reach the site. Included in the free plan.
โœ“
WAF (Web Application Firewall) โ€” Cloudflare WAF inspects incoming HTTP requests and blocks known attack patterns โ€” SQL injection attempts, XSS payloads, bot traffic.
Covers: DNS, Security & Monitoring โ€” 10 pts
๐Ÿ›ก
Layer 3

HTTP Security Headers

Small instructions sent with every page that tell the browser how to behave safely.

When a browser loads a page, the server sends invisible "headers" along with it. Security headers are instructions like: "don't let this page be embedded in another site" or "only load images from approved sources." They're a first line of defense against common web attacks.

โœ“
X-Frame-Options: DENY โ€” Prevents the site from being embedded in an iframe on another domain. Stops "clickjacking" โ€” where an attacker overlays a fake UI on top of your real site.
โœ“
X-Content-Type-Options: nosniff โ€” Tells the browser to never guess the file type. Prevents attacks where malicious content is disguised as a harmless file.
โœ“
Referrer-Policy: strict-origin-when-cross-origin โ€” Controls how much URL information is shared when clicking a link to another site. Prevents leaking page paths to third-party analytics.
โœ“
Permissions-Policy โ€” Explicitly disables browser APIs the site doesn't use: camera=(), microphone=(), geolocation=(). Even if an attacker injected code, they couldn't access these.
โœ“
Content-Security-Policy (CSP) โ€” Whitelists which domains can load scripts, styles, images, and frames. Configured in next.config.mjs โ€” any script not from an approved source is blocked, stopping cross-site scripting (XSS).
Covers: DNS, Security & Monitoring โ€” 10 pts
๐Ÿ—
Layer 4

Secrets & API Key Management

Keeping passwords and API keys out of the code and out of Git.

Every cloud service (Supabase, Stripe, Anthropic) gives you an API key โ€” like a password that grants access. If that key ends up in your GitHub repository, anyone who finds it can use your account, rack up charges, or steal data. The rule: secrets never go in code.

โœ“
.env.local (local development) โ€” All API keys are stored in a .env.local file on the developer's machine only. This file is listed in .gitignore โ€” Git never tracks it, so it can never be pushed to GitHub.
โœ“
Cloudflare Pages Secrets โ€” In production, secrets are stored as encrypted environment variables in the Cloudflare dashboard (wrangler pages secret put). They're injected at runtime โ€” the code never stores them directly.
โœ“
Service Role Key (server-side only) โ€” Supabase's admin service_role key bypasses row-level security. It is only used inside server-side API routes (/api/*) โ€” never in client-side code that ships to the browser.
โœ“
Anon Key (public, limited) โ€” The Supabase anon key is safe to use in the browser because Row Level Security policies limit what it can read or write โ€” it cannot access other users' data.
Covers: Infrastructure-as-Code โ€” 10 pts
๐Ÿ—„
Layer 5

Database Security (Row Level Security)

Even if someone gets into the database, they can only see what they're allowed to.

Supabase uses PostgreSQL with Row Level Security (RLS). RLS means you can write rules at the database level: "user A can only read rows where user_id = A." Even if an attacker finds a bug in the API, the database itself enforces access rules as a second line of defense.

โœ“
RLS Enabled on All Tables โ€” Every table (page_visits, journals, users) has RLS turned on. Without an explicit policy, no data is readable โ€” deny by default.
โœ“
Public Read Policy (visitor counter) โ€” The page_visits table has a SELECT policy that allows anyone to read counts (it's public data) but only the server-side API can INSERT or UPDATE using the service role key.
โœ“
User-Scoped Policies (journals) โ€” Journal entries have a policy: SELECT and INSERT are only allowed where auth.uid() = user_id. Users can only ever see their own data.
โœ“
No Direct Database Access โ€” The database is not exposed to the public internet. All access goes through Supabase's API layer, which enforces authentication before any query runs.
Covers: Visitor Counter + API โ€” 10 pts
โš™๏ธ
Layer 6

CI/CD Pipeline Security

Making sure broken or unsafe code never reaches the live site.

The CI/CD pipeline (GitHub Actions) runs automated checks on every single code change before it can be deployed. Think of it as a security guard at the door โ€” code has to pass inspection before it's allowed in.

โœ“
Branch Protection โ€” All changes must go through a Pull Request โ€” no one, including the owner, can push directly to the main branch. Every change is reviewed before merge.
โœ“
TypeScript Type Checking โ€” npx tsc --noEmit runs on every push. TypeScript catches a whole class of bugs (null references, wrong data types) that could cause security issues or crashes.
โœ“
Build Verification โ€” npx next build must succeed before deployment. A broken build fails the pipeline and the old version of the site stays live โ€” users are never served a broken page.
โœ“
No Secrets in Code โ€” A pre-push hook checks for hardcoded API keys. The .gitignore blocks .env files from being committed. Cloudflare Pages secrets are separate from the repo.
Covers: CI/CD Automation โ€” 10 pts
๐Ÿ“ˆ
Layer 7

Monitoring & Logging

Knowing when something goes wrong โ€” and having a record of what happened.

Security doesn't stop after you deploy. You need to watch for unusual activity: too many requests from one IP, errors spiking, API calls failing. Logs are the receipts โ€” they tell you what happened, when, and from where.

โœ“
Cloudflare Analytics โ€” Shows total requests, bandwidth, threats blocked, top countries, and bot traffic. Accessible from the Cloudflare dashboard โ€” no setup required.
โœ“
Cloudflare Firewall Events โ€” Every request the WAF blocks is logged with the rule that triggered it, the source IP, and the attack type. Useful for seeing what attacks were attempted.
โœ“
Supabase Logs โ€” Every API call to the database is logged in Supabase's dashboard โ€” query times, errors, auth events, and which user triggered each action.
โœ“
Budget Alerts โ€” Cloudflare and Supabase both have usage dashboards. Unusual spikes in traffic or database requests trigger visible alerts โ€” a sign of a potential attack or runaway process.
Covers: Logging & Alerts โ€” 10 pts

Security checklist โ€” 8 rules every cloud project should follow

โœ…Always use HTTPS โ€” never HTTP โ€” for any site that handles user data.
โœ…Store API keys in environment variables, never in code files.
โœ…Enable Row Level Security on every database table โ€” deny by default.
โœ…Use a WAF (like Cloudflare) to filter bad traffic before it hits your app.
โœ…Set security headers on every response โ€” X-Frame-Options, CSP, HSTS.
โœ…Require Pull Requests โ€” never push directly to your production branch.
โœ…Check your logs weekly โ€” unusual spikes are often the first sign of an attack.
โœ…Use least-privilege access โ€” give each service only the permissions it actually needs.

What happens without these layers?

No HTTPSPasswords and data travel as plain text โ€” anyone on the same Wi-Fi network can read them with a free tool like Wireshark.
No WAFAutomated bots scan every site on the internet. Without a WAF they find SQL injection and XSS vulnerabilities within hours of a site going live.
API keys in codeGitHub crawlers (and attackers) actively scan public repos for API keys. A leaked Supabase service key gives full database access โ€” every record, deleteable.
No Row Level SecurityA single API bug could expose every user's private data. RLS means even a compromised API can only see what the current user is allowed to see.
No CI/CD checksA typo or bad merge pushes broken code directly to production. Without automated build checks, users hit errors until someone notices manually.
No monitoringAn attacker could be brute-forcing your login page for days before you notice. Logs are the only way to detect attacks that don't break anything immediately.
โ† Architecture ViewProject StoryTeam Page
Educational content only. Security configurations shown are specific to this project and may not apply to every deployment.