> cs·fundamentals
interview 0% 26m read
6.3 ★ core [J][A][I] 15 interview Q's

Security fundamentals

OWASP Top 10:2025 awareness, the injection/XSS/CSRF trio and how they differ, hashing vs encryption, password salting, and least privilege.

Security at the senior level isn’t memorizing exploits — it’s holding an accurate threat model and knowing the few mistakes that cause most real breaches. This chapter anchors on the OWASP Top 10:2025, then drills the attacks you’ll be asked to distinguish (injection, XSS, CSRF) and the cryptography fundamentals everyone gets wrong (hashing vs encryption, salting). The through-line: almost every entry on the list is a trust-boundary failure — data crossed from “untrusted” to “trusted” without anyone checking it.

OWASP Top 10:2025 — the ordering

The OWASP Top 10:2025 was announced in November 2025 and finalized in early 2026, built on 175,000+ CVE records across ~2.8 million applications plus a survey of security experts. Three shifts matter most: A01 Broken Access Control stays #1 (it has held the top spot since 2003) and now absorbs SSRF, whose root cause is an access-control failure; A03 Software Supply Chain Failures is the headline new entry, surging into the top three; and injection has dropped to A05. The exact list:

RankCategoryWhat changed in 2025
A01Broken Access Control#1 since 2003; now absorbs SSRF (its root cause is access control)
A02Security Misconfigurationrose from #5 in 2021
A03Software Supply Chain Failuresnew framing — expanded from 2021's "Vulnerable & Outdated Components"; surged into the top 3
A04Cryptographic Failures
A05Injectiondropped from #3 (2021) to #5
A06Insecure Design
A07Authentication Failures
A08Software or Data Integrity Failures
A09Security Logging & Alerting Failures
A10Mishandling of Exceptional Conditionsthe only entirely new standalone category
OWASP Top 10:2025 — confirm against owasp.org/Top10/2025 before quoting in an interview.

The two facts an interviewer is most likely to probe: SSRF is no longer its own entry because it’s fundamentally an access-control failure (so it folded into A01), and supply-chain risk jumped into the top three after a wave of compromised packages and build pipelines. The other genuinely new 2025 category is A10 Mishandling of Exceptional Conditions — errors and edge cases handled in ways that leak information or fail open (e.g. a crash that defaults to “access granted”).

Injection, XSS, and CSRF — how they differ

These three get conflated constantly. The crisp distinction is who gets attacked and what trust boundary is crossed:

Three trust-boundary diagrams: injection reaching the database, XSS executing in a victim browser, and CSRF using a victim’s cookies to hit your server.INJECTION → server/DBattackerserverdatabaseinput parsedas SQL/commandsXSS → victim’s browserattackeryour page(stored markup)victim browserruns attacker JSCSRF → victim’s sessionattacker sitein victim browseryour servertrusts the cookieauthed request+ victim’s cookies
FIG 1 · who gets attacked Injection crosses into the server/DB; XSS crosses into a victim's browser; CSRF rides a victim's existing session from an attacker's site.
AttackWho is the victimMechanismPrimary defense
Injection (SQLi)the server / databaseinput is parsed as SQL/commandsparameterized queries (bind parameters)
XSSanother user's browserattacker markup runs as JS in the victim's pageoutput-encode + Content-Security-Policy
CSRFthe user's sessionvictim's browser is tricked into sending an authed requestanti-CSRF token + SameSite cookies
Injection hits the server; XSS runs in a victim's browser; CSRF abuses a victim's existing session.
SQL injection — the string-concatenation bug and its fix

The vulnerability is building a query by concatenating user input, so the input can change the query’s structure:

// VULNERABLE: input is glued into the SQL text
const q = "SELECT * FROM users WHERE email = '" + email + "'";
// If email = "' OR '1'='1", the WHERE is always true → dumps every user.
// If email = "'; DROP TABLE users; --", you've lost the table.

The fix is a parameterized (prepared) query: the SQL structure is fixed up front, and the input is sent separately as data that the driver binds — it can never be parsed as SQL:

// SAFE: the ? is a bound parameter, never concatenated into the query text
const rows = await db.query(
  "SELECT * FROM users WHERE email = ?",
  [email]
);

The principle generalizes: never build an interpreted string (SQL, shell, HTML) by gluing in untrusted input. Use parameter binding for SQL, and context-aware output encoding for HTML.

For XSS, the equivalent bug is echoing user input into a page without encoding it. If a comment body containing <script>steal()</script> is written straight into the HTML, the browser runs it as code for every viewer. The defense is to output-encode untrusted data for its context (so < becomes &lt; and the markup renders as inert text) and to layer a Content-Security-Policy that refuses inline scripts.

Hashing vs encryption, and why salting matters

PropertyHashingEncryption
Directionone-way — cannot be reversedreversible with the key
Keyno key (a salt isn't a key)requires a secret key
Use it forpasswords, integrity/checksumsdata in transit (TLS), secrets at rest
Right toolbcrypt / argon2 (slow, salted)AES-GCM, TLS
"Get the original back?"No — you only compare hashesYes — decrypt with the key
If you ever need the plaintext back, you wanted encryption; if you only ever verify, you wanted hashing.

A plain hash isn’t enough for passwords for two reasons. First, fast hashes like MD5 or SHA-256 let an attacker try billions of guesses per second against a stolen hash. Second, without a salt, identical passwords produce identical hashes, so one cracked hash cracks every user who shares it, and precomputed rainbow tables work instantly. The answer is a slow, salted password hashbcrypt or argon2 — which bakes in a per-user salt and a deliberately expensive, tunable work factor.

Hashing a password with bcrypt (salt + work factor built in)
import bcrypt from "bcrypt";

// REGISTER: bcrypt generates a random per-user salt and bakes it into the hash.
// The cost factor (12) sets how slow each hash is — tune it up as hardware speeds up.
const hash = await bcrypt.hash(plaintextPassword, 12);
// → "$2b$12$Q9s...salt...hash"  (algo · cost · salt · digest, all in one string)

// LOGIN: never decrypt — re-hash the attempt with the stored salt and compare.
const ok = await bcrypt.compare(attempt, hash);   // true / false

Three things to notice. The salt is random and per-user, embedded in the output string, so two users with the same password get different hashes. The cost factor makes each hash deliberately slow, so brute-forcing a stolen hash is infeasible. And login never decrypts — it re-hashes the attempt and compares, because a hash is one-way by design.

Two cross-cutting principles tie it together. Least privilege: every user, service, and token gets the minimum access needed and nothing more, so a compromise has a small blast radius. Secrets management: credentials live outside the codebase, are rotated, and are scoped — never in source control, never in a plaintext config committed to git.

Securing the supply chain (A03)

You ship far more code you didn’t write than code you did — dependencies, their transitive dependencies, base images, build tools. A03 Software Supply Chain Failures jumped into the top three because that’s where attackers now aim: a malicious or typosquatted package, a compromised maintainer account, or a poisoned build step lets them into thousands of apps at once. Three layers of defense, plus provenance:

  • Dependency scanning (SCA) — scan your dependency tree for known CVEs and pin versions with a lockfile (npm audit, Dependabot, Snyk, Trivy). The highest-leverage one, because most breaches here are known vulnerabilities in outdated packages nobody updated.
  • SAST (static analysis) — analyze your source for vulnerable patterns before it runs (Semgrep, CodeQL, SonarQube), wired into CI so a risky pattern blocks the PR.
  • DAST (dynamic analysis) — probe the running app from the outside for exploitable behavior (OWASP ZAP), catching what static analysis can’t see.
  • SBOM + SLSA (provenance) — a Software Bill of Materials lists exactly what’s in a build; SLSA is a framework of build-integrity levels that attest an artifact came from your trusted pipeline, unmodified — so a tampered build is detectable.
ToolAnalyzesRunsCatches
SCA (dep scan)your dependenciesCI / on updateknown CVEs in packages you pull in
SASTyour source codeCI, pre-mergevulnerable patterns (injection sinks, hardcoded secrets)
DASTthe running appstaging / CIexploitable behavior from outside (auth, XSS, headers)
SCA scans what you import, SAST scans your code, DAST attacks the running app — layer all three.

The cheap, high-impact habits: commit a lockfile, turn on automated dependency updates, give CI tokens least privilege (a leaked CI secret is itself a supply-chain foothold), and be wary of packages that run install scripts.

01 Learning objectives

0 / 5 done

02 Curated reading

03 Knowledge check

knowledge check6 questions · pass ≥ 70%
  1. 01easy

    The OWASP Top 10:2025 #1 category is:

  2. 02easy

    The highest-leverage defense against OWASP A03 (supply-chain) failures is…

  3. 03medium

    The correct primary defense against SQL injection is:

  4. 04medium

    Passwords should be stored using:

  5. 05medium

    SAST vs DAST:

  6. 06hard

    Hashing vs encryption:

04 Interview questions

browse all ↗

What gets asked on this topic — tap a card for how to approach it, the follow-ups, and the trap. Company tags are best-effort & sourced.

  • Commonly asked senior concept common What sits at #1 of the OWASP Top 10:2025, and name a couple of categories that are new or changed this edition.

    A01: Broken Access Control is #1 — and in the 2025 edition it now absorbs Server-Side Request Forgery (SSRF). It means users acting outside their intended permissions: missing authorization checks, IDOR, privilege escalation.

    What is new/notable in 2025:

    - A03: Software Supply Chain Failures is new and surged into the top 3 — broadened from the old 'Vulnerable and Outdated Components' to the whole dependency/build ecosystem.
    - A10: Mishandling of Exceptional Conditions is brand new — improper error handling, failing open, logic errors on abnormal input.
    - The full order: A01 Broken Access Control, A02 Security Misconfiguration, A03 Software Supply Chain Failures, A04 Cryptographic Failures, A05 Injection, A06 Insecure Design, A07 Authentication Failures, A08 Software/Data Integrity Failures, A09 Logging & Alerting Failures, A10 Mishandling of Exceptional Conditions.

    Red flag Quoting the 2021 list as current (e.g. putting Injection at #3 or naming 'Vulnerable and Outdated Components') — in 2025 Injection is A05 and supply-chain is its own A03.

    source: OWASP Top 10:2025 ↗
  • Commonly asked mid concept very common How do XSS and CSRF differ, and how do you defend against each?

    XSS injects attacker-controlled JavaScript that runs in the victim's browser in *your* site's origin. Defenses: context-aware output encoding, a strict Content-Security-Policy, sanitize any HTML you must render, and HttpOnly cookies so stolen script cannot read the session token.

    CSRF tricks an already-authenticated browser into firing an unwanted state-changing request (the browser auto-attaches the cookie). Defenses: anti-CSRF tokens, SameSite cookies, and verifying the Origin/Referer header.

    The crisp distinction: XSS abuses the site's trust in user input; CSRF abuses the site's trust in the user's authenticated session.

    Red flag Claiming CSRF tokens stop XSS — if you have XSS, the attacker's script can just read the CSRF token and forge a valid request.

    source: OWASP — Cross Site Request Forgery (CSRF) ↗
  • Commonly asked junior concept very common What is SQL injection, and what is the *one* correct defense?

    SQL injection is when untrusted input is concatenated into a query so the attacker can change its structure — e.g. ' OR '1'='1 to bypass a login, or '; DROP TABLE users;-- to destroy data.

    The primary defense is parameterized queries / prepared statements: the SQL text and the data travel on separate channels, so input is always treated as a value, never as code. ORMs do this for you when used correctly.

    Defense in depth adds least-privilege DB accounts and allow-list input validation — but escaping by hand is error-prone and not the real fix. The principle (separate code from data) generalizes to *all* injection: OS command, LDAP, NoSQL, etc.

    Red flag Saying 'sanitize/escape the input' as the primary fix — parameterization is the answer; ad-hoc escaping misses cases.

    source: OWASP — SQL Injection Prevention Cheat Sheet ↗
  • Commonly asked mid concept very common Hashing vs encryption — what's the difference, and which do you use for passwords?

    Encryption is reversible: with the key you can recover the plaintext. Use it for data you must read back — data in transit (TLS), secrets at rest.

    Hashing is one-way: you cannot invert it; you can only re-hash a candidate and compare. Use it when you only ever need to *verify*, never recover — exactly the password case.

    So passwords are hashed, not encrypted — if you can decrypt them, so can an attacker who steals your key. And not just any hash: use a slow, memory-hard password hash with a per-password salt.

    Red flag Saying you 'encrypt passwords' — that is the wrong primitive; passwords should be hashed with a dedicated password hash so they are non-recoverable.

    source: OWASP — Password Storage Cheat Sheet ↗
  • Commonly asked senior concept common Why is SHA-256 a bad choice for storing passwords, and what's the salt for?

    General-purpose hashes like SHA-256 are *designed to be fast* — which is exactly wrong for passwords. An attacker with the hash file can compute billions of guesses per second on a GPU.

    Use a slow, memory-hard password hash: OWASP recommends Argon2id (then scrypt; bcrypt only for legacy). Their tunable work factor keeps verification fast for you but brute force expensive for attackers.

    The salt is a unique random value per password, stored alongside the hash. It ensures two users with the same password get different hashes and defeats precomputed rainbow tables — the attacker must crack each password individually. (A site-wide secret pepper can be layered on top.)

    Red flag Using a fast hash (MD5/SHA-1/SHA-256) for passwords, or reusing one salt for everyone — both leave you open to rainbow-table and GPU attacks.

    source: OWASP — Password Storage Cheat Sheet ↗
  • Commonly asked senior concept common What is the principle of least privilege, and how does it apply to secrets management?

    Least privilege: every user, service, and credential gets only the permissions it needs to do its job — no more, no less. It shrinks the blast radius when something is compromised.

    Applied to secrets:

    - Don't hardcode secrets in source or commit them to git; store them in a secrets manager (Vault, AWS/GCP Secrets Manager) or injected env vars.
    - Scope each secret narrowly — a service's DB credential can touch only its own schema, not everything.
    - Rotate secrets, and prefer short-lived/dynamic credentials over long-lived static keys.
    - Audit access so a leaked key is detectable and revocable.

    This maps to OWASP A02 (Security Misconfiguration) and A08 (Integrity Failures).

    Red flag Granting broad, permanent admin credentials 'to keep things simple' — it maximizes blast radius and violates least privilege.

    source: OWASP — Secrets Management Cheat Sheet ↗
  • Commonly asked senior concept common What is Software Supply Chain risk (OWASP A03:2025), and how do you reduce it?

    Your app is mostly code you didn't write — third-party packages, their transitive deps, base images, and the build/CI pipeline itself. A03:2025 covers compromises anywhere in that chain: a malicious or vulnerable dependency, a typosquatted package, a poisoned build step, or a tampered artifact.

    Mitigations:

    - Pin and lock dependencies (lockfiles, hashes) so builds are reproducible.
    - Scan deps for known CVEs (SCA tools) and patch promptly.
    - Generate an SBOM so you know what you ship.
    - Verify provenance / sign artifacts (e.g. Sigstore) and protect CI credentials.
    - Minimize and pin base images.

    This was broadened in 2025 from the older 'Vulnerable and Outdated Components' to the whole ecosystem.

    Red flag Treating supply-chain security as just 'keep dependencies updated' — it also covers the build pipeline, artifact provenance, and transitive deps.

    source: OWASP Top 10:2025 — Introduction (A03 Software Supply Chain Failures) ↗
  • Commonly asked mid trick occasional A login endpoint returns 'user not found' for unknown emails and 'wrong password' for known ones. What's wrong?

    It is a user-enumeration vulnerability. The two distinct messages let an attacker probe which emails are registered, building a target list for credential stuffing, phishing, or password spraying.

    Fix: return a single generic message — 'invalid email or password' — for both cases, and keep the response *timing* uniform (still run a dummy password hash when the user doesn't exist) so the attacker can't distinguish via latency either. The same care applies to signup ('email already in use') and password-reset flows.

    This ties to OWASP A07 (Authentication Failures).

    Red flag Fixing only the message text but leaving a timing side-channel (fast 'not found' vs slow bcrypt compare) that still leaks which accounts exist.

    source: OWASP — Authentication Cheat Sheet (account enumeration) ↗
  • ★ must-know Commonly asked senior concept common What is the root cause shared by all injection attacks, and why is parameterization the fix?

    Every injection flaw — SQL, OS command, LDAP, NoSQL, XPath, even XSS — has the same root cause: untrusted data is interpreted as code because data and instructions travel on the same channel. The interpreter can't tell which bytes you meant as a value and which as syntax, so attacker input rewrites the command's structure.

    Parameterization fixes this by *separating the channels*: the query/command template (the code) is sent and compiled independently of the parameters (the data), so user input is bound as a literal value and can never change the parsed structure. SELECT * FROM users WHERE id = ? with a bound parameter treats '; DROP TABLE as a harmless string.

    This is why the generalized defense is 'keep code and data separate' — prepared statements for SQL, argument arrays (not shell strings) for OS commands, and context-aware encoding for output. Escaping/blocklisting is a fragile fallback, not the primary control.

    What a strong answer covers
    • Root cause of all injection: untrusted data is parsed as code because they share one channel.

    • Parameterization sends template and data separately, so input binds as a literal and can't alter structure.

    • Generalizes beyond SQL: arg arrays for OS commands, parameterized APIs for LDAP/NoSQL, encoding for output (XSS).

    • Escaping/blocklists are fallbacks, not the fix — they miss encodings and edge cases.

    Quick self-check

    Why do parameterized queries prevent SQL injection?

    Red flag Thinking injection is a SQL-specific problem solved by a SQL-specific trick — it's a universal code/data-confusion flaw, and the universal fix is separating the two, not escaping characters.

    source: OWASP — Injection Prevention Cheat Sheet ↗
  • Commonly asked senior concept common What is an IDOR, and why does Broken Access Control sit at #1 of the OWASP Top 10:2025?

    An IDOR (Insecure Direct Object Reference) is the canonical Broken Access Control bug: an endpoint exposes a reference to an object — /api/orders/1043 — and the server returns it based on the URL alone, without checking that *this* user is allowed to see *that* object. Change 1043 to 1044 and you read someone else's order.

    It's #1 in OWASP Top 10:2025 (as it was in 2021) because authorization is per-request, per-object logic that's easy to forget on some path, hard for scanners to find, and devastating when wrong — it's the most commonly found weakness. The 2025 edition also folded SSRF into this category.

    The fix is to enforce authorization server-side on every request, checking ownership/role against the authenticated identity — never trusting a client-supplied ID, never relying on the object reference being unguessable, and denying by default. Using unpredictable IDs (UUIDs) is hardening, not a substitute for the check.

    What a strong answer covers
    • IDOR: the server returns an object from a client-supplied reference without verifying the user is authorized for it.

    • #1 because authz is per-object, easy to miss, hard to scan for, and catastrophic — the most prevalent weakness.

    • Enforce authorization server-side on every request, deny by default, check ownership against the session identity.

    • Unguessable IDs (UUIDs) are hardening — not a replacement for the access-control check; SSRF now lives in this category (2025).

    Red flag Relying on 'unguessable' object IDs or hiding the endpoint instead of performing a real per-request authorization check — security by obscurity, not access control.

    source: OWASP Top 10:2025 — A01 Broken Access Control ↗
  • Commonly asked mid concept common What is defense in depth, and why isn't input validation alone enough to stop XSS?

    Defense in depth is layering independent controls so that no single failure is fatal — if one layer is bypassed, another still stands. No control is perfect, so you don't bet everything on one.

    For XSS, input validation alone is insufficient because the danger depends on output context, not the input. A string that's harmless in an HTML body can break out inside a <script> block, an HTML attribute, a URL, or a CSS context — and validation at the input boundary can't know where the value will eventually be rendered. Worse, data arrives from many sources (DB, other services) that never passed your input filter.

    So you layer: context-aware output encoding at the point of rendering (the primary defense), a strict Content-Security-Policy as a backstop that limits what injected script can do, HttpOnly cookies so stolen script can't read the session token, and input validation as one more (not the only) layer.

    What a strong answer covers
    • Defense in depth = independent layers; a single bypass shouldn't compromise the system.

    • XSS safety depends on output context (HTML body vs attribute vs JS vs URL), which input validation can't anticipate.

    • Primary defense is context-aware output encoding at render time; CSP is the backstop.

    • Data also enters from sources that never hit your input filter (DB, other services), so input validation alone is incomplete.

    Red flag Treating input validation as the complete XSS fix — encoding must happen at output based on context, and CSP/HttpOnly provide the additional layers that catch what slips through.

    source: OWASP — Cross Site Scripting Prevention Cheat Sheet ↗
  • Commonly asked junior concept very common What's the difference between authentication and authorization, and why must both be enforced server-side?

    Authentication (authn) is *who are you?* — verifying identity (password, token, passkey). Authorization (authz) is *what are you allowed to do?* — checking that the verified identity has permission for this action/resource. Authn always comes first; authz decides what that authenticated identity may access.

    Both must be enforced server-side because the client is fully under the attacker's control: hiding a button, disabling a form field, or checking a role in JavaScript stops only honest users. An attacker just crafts the HTTP request directly (curl, Burp), bypassing every front-end check. The browser is a convenience layer, never a trust boundary.

    So the server must, on every request, verify the credential *and* re-check that this identity is permitted — front-end checks are UX, not security.

    What a strong answer covers
    • Authn = who you are (verify identity); authz = what you may do (verify permission). Authn precedes authz.

    • The client is attacker-controlled — any check in JS/HTML can be bypassed by crafting the raw request.

    • Enforce both on the server, every request; front-end checks are UX, not a trust boundary.

    • Skipping the server-side authz re-check is exactly the Broken Access Control (#1) failure.

    Quick self-check

    An admin-only button is hidden in the UI for non-admins, but the /admin/delete endpoint has no server-side role check. What's true?

    Red flag Enforcing access control only in the UI (hidden buttons, disabled fields) — the server must re-verify, since the client can forge any request directly.

    source: OWASP — Authorization Cheat Sheet ↗
  • Commonly asked mid concept common What is Security Misconfiguration (OWASP A02:2025), and give concrete examples.

    Security Misconfiguration is risk introduced by how systems are set up rather than by code flaws — and it climbed to A02 in the 2025 Top 10, reflecting how common it is across the increasingly complex, configurable stacks we run.

    Concrete examples: default or unchanged credentials; verbose error pages or stack traces leaking internals in production; unnecessary features/ports/services left enabled; an S3 bucket or admin console open to the public; missing security headers (HSTS, CSP); directory listing on; debug mode on in prod; overly permissive CORS.

    The defense is a repeatable, hardened baseline: minimal install (remove what you don't use), secure defaults, infrastructure-as-code so every environment is configured identically and reviewably, automated configuration scanning, and segregated environments. It overlaps tightly with least privilege and supply-chain hygiene.

    What a strong answer covers
    • Risk from setup, not code — defaults, exposed services, leaked errors, missing headers.

    • Rose to A02 in 2025 because modern stacks have huge configurable surface area.

    • Examples: default creds, public buckets, debug mode in prod, verbose stack traces, permissive CORS.

    • Fix with a hardened, minimal, repeatable baseline (IaC + config scanning + identical environments).

    Red flag Treating misconfiguration as a one-time setup task — config drifts across environments and over time; without IaC and scanning, prod quietly diverges into an insecure state.

    source: OWASP Top 10:2025 — A02 Security Misconfiguration ↗
  • Commonly asked senior concept occasional Why store a session token in an HttpOnly, Secure, SameSite cookie rather than localStorage?

    localStorage is fully readable by any JavaScript on the page — so a single XSS flaw lets an attacker's script exfiltrate the token instantly. A cookie marked HttpOnly is invisible to JavaScript: even with XSS, the script can't read the token to steal it.

    The other flags close the remaining gaps: Secure sends the cookie only over HTTPS (no plaintext interception), and SameSite (Lax/Strict) stops the browser from auto-attaching it on cross-site requests, which mitigates CSRF — the attack that cookie-based auth otherwise invites.

    The tradeoff: HttpOnly cookies are auto-sent by the browser, so you take on CSRF risk and must defend it (SameSite + anti-CSRF tokens). localStorage avoids CSRF but trades it for far worse XSS token theft. The consensus is HttpOnly cookies with CSRF defenses, because XSS token exfiltration is the more dangerous failure.

    What a strong answer covers
    • localStorage is readable by any JS — one XSS = instant token theft.

    • HttpOnly hides the cookie from JavaScript, so XSS can't read/exfiltrate it.

    • Secure = HTTPS-only; SameSite blocks cross-site auto-send, mitigating CSRF.

    • Cookies trade XSS-theft risk for CSRF risk — so pair them with SameSite + anti-CSRF tokens.

    Red flag Storing JWTs/session tokens in localStorage 'for convenience' — it's directly readable by any injected script, turning any XSS into full account takeover.

    source: OWASP — Session Management Cheat Sheet ↗
  • Commonly asked mid trick occasional What is encoding (Base64), and why is it not a security control?

    Encoding transforms data into another representation for safe transport or storage — Base64, URL-encoding, hex. It's a fully reversible, keyless, public algorithm: anyone can decode it with no secret. Its purpose is *compatibility* (e.g. putting binary in a text/JSON field), not secrecy.

    That's the trap: Base64 *looks* scrambled, so people mistake it for protection. But dXNlcjpwYXNz decodes to user:pass in one trivial step — it provides zero confidentiality.

    The three are distinct: encoding = reversible, no key, for compatibility; encryption = reversible *with a key*, for confidentiality; hashing = one-way, no key, for integrity/verification. Anytime someone says 'we Base64 the password before sending,' that's a misunderstanding — over HTTP it's plaintext; you need TLS (encryption) for confidentiality.

    What a strong answer covers
    • Encoding is reversible and keyless — its job is transport/compatibility, not secrecy.

    • Base64 'looks' encrypted but decodes in one public step → zero confidentiality.

    • Distinguish the trio: encoding (no key, compat) vs encryption (key, confidentiality) vs hashing (one-way, integrity).

    • Base64-ing a credential adds no protection; only TLS/encryption provides confidentiality on the wire.

    Quick self-check

    Which statement about Base64 encoding is correct?

    Red flag Mistaking Base64 (or any encoding) for encryption — it's a reversible public transform with no key and provides no confidentiality whatsoever.

    source: OWASP — Cryptographic Storage Cheat Sheet ↗