skip to content

questions

18

Walk me through exactly what a client puts in the HTTP Authorization header when using Basic authentication, and what protection that encoding gives you.

level: juniorimportance: must knowfreq 72%

answer

  1. base64(userid ':' password)
  2. encoding, not encryption — one-step decode
  3. split on FIRST colon; user id has no colon
  4. stateless: header on every request
  5. TLS mandatory; scrub Authorization from logs

basics

~20 s

The client sends Authorization: Basic <base64 of userid:password>, recomputed on every request. Base64 is reversible encoding, not encryption or hashing — anyone who captures the header decodes the password instantly, so only TLS provides confidentiality.

solid answer

~50 s

Basic joins the user id and password with a single colon, encodes those bytes with base64, and sends them as `Authorization: Basic YWxpY2U6czNjcmV0`. The user id must not contain a colon; the server splits on the **first** colon, so the password may contain one. Base64 is a transport encoding — it exists so arbitrary bytes survive an HTTP header, not to hide anything. `base64 -d` recovers the password in one step, so Basic is only acceptable inside TLS. Basic is stateless: there is no session, so the client attaches the same header to every request, and the server re-verifies the password every time. A server advertises Basic with `WWW-Authenticate: Basic realm="...", charset="UTF-8"` on a 401; the `realm` is just a label naming the protection space the credentials belong to. `curl -u alice:s3cret` builds the header for you.

code

http · 11 lines
http
GET /reports/2024 HTTP/1.1
Host: api.example.com

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Reports API", charset="UTF-8"

GET /reports/2024 HTTP/1.1
Host: api.example.com
Authorization: Basic YWxpY2U6czNjcmV0

HTTP/1.1 200 OK

go deeper

for a junior

Recite the construction precisely — join with a colon, base64, Authorization: Basic ... — and say clearly that base64 is reversible encoding, so TLS is what protects it.

for a middle

Add the parse rule (split on the first colon), statelessness and per-request resending, and the realm/charset parameters on the 401 challenge.

for a senior

Bring in operational exposure: header scrubbing in access logs and APM, keeping secrets off command lines, and why per-request verification cost matters.

for a principal

Frame when Basic is an acceptable machine-to-machine choice (high-entropy generated secret, TLS everywhere, no lifecycle needs) versus when a token scheme with expiry, scope and revocation is required.

## What Basic authentication is Basic is the simplest scheme in the HTTP authentication framework, defined today by RFC 7617 (it updates the older RFC 2617 text). It transmits a user id and a password on each request. There is no challenge computation, no nonce, no signature — the client hands over the secret itself and the server checks it. ## Building the header value The algorithm is fully mechanical: 1. Concatenate the user id, a single `:` (colon, U+003A), and the password. 2. Encode that string to bytes (UTF-8, see the `charset` parameter). 3. Base64-encode those bytes. 4. Send `Authorization: Basic <that base64 string>`. For `alice` / `s3cret` the joined string is `alice:s3cret`, whose base64 form is `YWxpY2U6czNjcmV0`. The scheme name (`Basic`) is case-insensitive; exactly one space separates it from the credentials. ## Encoding is not protection This is the single point interviewers are checking. Base64 is a binary-to-text encoding: it maps three bytes onto four printable characters so that bytes outside the header's allowed character set (spaces, non-ASCII, control characters) can travel in an HTTP header. It uses no key, so it is trivially reversible — `echo YWxpY2U6czNjcmV0 | base64 -d` prints `alice:s3cret`. It is not encryption (no key, no confidentiality) and not hashing (it is reversible, unlike a one-way digest). Anyone who can read the request — a passive tap on plaintext HTTP, a logging proxy, an APM tool that captures headers, a browser extension — reads the password. The consequence: Basic must run inside TLS, and access logs and telemetry must scrub the `Authorization` header. RFC 7617 is explicit that Basic provides no confidentiality on its own and must be paired with a secure channel. ## The colon rule and empty values The separator is the *first* colon. Therefore the **user id must not contain a colon** — if it does, the server cannot parse the pair unambiguously and the credential is invalid. The password may contain colons freely: `bob:a:b:c` is user `bob`, password `a:b:c`. Empty halves are legal at the syntax level: `bob:` (`Ym9iOg==`) is user `bob` with an empty password, and `:onlypass` (`Om9ubHlwYXNz`) is an empty user id — some APIs use this shape to carry a single API key in the password field (`curl -u :$TOKEN`). ## Sent on every request Basic is stateless. HTTP itself has no memory between requests, and Basic adds none: there is no server-side session created by authenticating. The client therefore attaches the same `Authorization` header to every request in the protected space. Two consequences follow. First, the exposure window is not "one login" but "every single request" — any one captured request leaks the password. Second, the server pays the password-verification cost on every request, which matters when the stored password is a deliberately slow hash. ## Where the realm fits When the server wants to prompt for credentials it replies `401 Unauthorized` with `WWW-Authenticate: Basic realm="Reports API", charset="UTF-8"`. `realm` is a human-readable label that names the *protection space*: clients (and browsers) cache credentials against origin + realm and reuse them for other URLs under the same space. It carries no security by itself; it exists so a client knows which stored credential applies and so a browser dialog can say what it is asking for. `charset="UTF-8"` tells the client to encode the credentials as UTF-8 before base64. ## Tooling `curl -u alice:s3cret https://api.example.com/x` builds the header and, for Basic, sends it **preemptively** on the first request rather than waiting for a 401. `curl -u alice` prompts for the password so it does not land in your shell history or the process list — a real operational detail, since command lines are visible to other users via `ps` and end up in `~/.zsh_history`. ## When Basic is still reasonable Despite its reputation, Basic is fine for machine-to-machine calls over TLS with a high-entropy generated secret rather than a human password: it is trivially implementable in any client, needs no library, and has no token lifecycle. It is a poor fit for browser-facing user login (no logout, no session control, credentials cached by the browser, no MFA path) and for anything crossing a network you do not control unencrypted.

  • What happens if the password itself contains a colon? What if the user id does?
    A password with colons is fine: the server splits the decoded string at the first colon, so everything after it is the password. A user id containing a colon is not representable — the parse would silently move part of the name into the password — so RFC 7617 forbids it, and such a credential must be rejected.
  • Does authenticating with Basic create a session on the server?
    No. Basic is stateless: the credentials travel on every request and the server re-verifies them each time. That is why there is no protocol-level logout for Basic — the browser simply keeps replaying the cached credential — and why per-request password verification cost becomes a capacity concern.

Base64 is like writing the password in a different alphabet, not locking it in a safe: no key is needed to read it back, only the alphabet chart everyone already has.

saying these in an interview costs you the question

  • Saying base64 encrypts or hashes the password, or calling it 'encoded so it is safe'
  • Claiming the credentials are sent only once at login and a session takes over afterwards
  • Thinking the realm value adds security rather than just naming a protection space
  • Believing the separator is configurable, or that user ids may contain colons
  • Assuming Basic over plain HTTP is acceptable on a 'trusted' internal network

context

open as a page

How is a bearer token transmitted on an HTTP request per RFC 6750, and what does the word 'bearer' actually mean about how the server treats it?

level: juniorimportance: must knowfreq 70%

basics

~20 s

Send Authorization: Bearer <token> on each request, over TLS. 'Bearer' means possession alone proves authorization: the request carries no proof of who is holding it, so whoever copies the token can use it exactly like the legitimate client.

open as a page

Walk through the HTTP challenge-response authentication flow: what does a 401 Unauthorized response carrying a WWW-Authenticate header tell the client, and what exactly does the client send back?

level: juniorimportance: must knowfreq 72%

basics

~20 s

The server refuses with 401 and a WWW-Authenticate header naming an authentication scheme, usually plus a realm. The client gets credentials for that scheme and retries the same request with an Authorization header. HTTP is stateless, so the header repeats on every later request.

open as a page

Why does RFC 7617 require HTTP Basic authentication to be used only over a confidential channel such as TLS, and what concretely goes wrong if a service accepts Basic over plaintext HTTP?

level: middleimportance: must knowfreq 58%

basics

~20 s

Basic transmits the reusable password itself, base64-encoded, on every single request. Without TLS any observer — network tap, proxy, log — reads and replays it forever. TLS is the only thing supplying confidentiality; the scheme supplies none.

open as a page

An API rejects a request that carried an `Authorization: Bearer` header. Explain the difference between answering with `WWW-Authenticate: Bearer error="invalid_token"` and `error="insufficient_scope"`, and which HTTP status code belongs with each.

level: middleimportance: must knowfreq 50%

basics

~20 s

invalid_token goes with 401: the token is expired, revoked or malformed, so a fresh token may work — clients refresh and retry. insufficient_scope goes with 403: the token is valid but lacks the required privilege, so retrying with the same token is pointless.

open as a page

Because a value sent in `Authorization: Bearer` is honoured on possession alone, what design measures reduce the blast radius of one that has been stolen from a production system?

level: seniorimportance: must knowfreq 48%

basics

~20 s

Shrink what a stolen token buys: short lifetime, narrow audience and scope, TLS everywhere, never in URLs or logs. Add revocation you can actually execute, replay detection, and — when it matters — sender-constrained carriage such as mTLS-bound tokens or DPoP.

open as a page

RFC 6750 permits an access token in a URI query parameter (`?access_token=...`) but strongly discourages it. What are the leakage paths, and what does correct carriage look like instead?

level: middleimportance: should knowfreq 38%

basics

~20 s

URLs are recorded everywhere: server and proxy access logs, browser history, bookmarks, Referer headers to third parties, shared links, crash reports, CDN analytics. Use Authorization: Bearer, add Cache-Control: no-store, and redact the header from all logging.

open as a page

HTTP defines both 401 Unauthorized with WWW-Authenticate and 407 Proxy Authentication Required with Proxy-Authenticate. What is the difference, and which request header answers each?

level: middleimportance: should knowfreq 40%

basics

~20 s

401 plus WWW-Authenticate comes from the origin server (or a gateway acting as one) and is answered with Authorization, which travels end to end. 407 plus Proxy-Authenticate comes from the intermediary proxy you are talking to and is answered with Proxy-Authorization, which that proxy consumes and removes.

open as a page

Walk through how HTTP Digest Authentication (RFC 7616) authenticates a request: what the server sends in its WWW-Authenticate challenge, what the client puts in the Authorization header, and how the `response` hash is computed.

level: middleimportance: should knowfreq 30%

basics

~20 s

The server answers 401 with WWW-Authenticate: Digest carrying realm, a server-generated nonce, qop and algorithm. The client replies with Authorization: Digest containing username, realm, uri, nonce, nc, cnonce, qop and a response hash built from the password plus the method and URI. The password itself never travels.

open as a page

Many HTTP clients attach the Basic `Authorization` header to the first request instead of waiting for a 401 challenge. Why is preemptive sending common, and what risks does it introduce in production?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Preemptive sending skips a wasted round trip and works with APIs that never challenge. The risk is broadcasting the password before you know the peer deserves it — to redirect targets, wrong hosts, unauthenticated endpoints, proxies and logs.

open as a page

An HTTP response returns 401 with more than one WWW-Authenticate challenge, for example both a Negotiate challenge and a Basic one. How should a client handle that, and what makes the challenge list hard to parse correctly?

level: seniorimportance: should knowfreq 26%

basics

~20 s

A server may offer several schemes; the client picks the strongest one it supports and ignores the rest, answering with a single Authorization header. Parsing is tricky because challenges are comma-separated and so are their auth-params, so a naive split on commas cannot tell where one challenge ends.

open as a page

A team proposes HTTP Digest Authentication for a new internal API, arguing it avoids sending passwords over the wire. How would you evaluate that proposal against Basic Authentication over TLS or bearer tokens?

level: principalimportance: should knowfreq 26%

basics

~20 s

Reject it. Digest's only advantage was hiding the password on a cleartext link, which TLS already solves. It forces password-equivalent server-side storage (no bcrypt), leaves bodies and responses unencrypted, is trivially downgraded by an active attacker, and offers no expiry, scoping, revocation or delegation — all of which tokens give you.

open as a page

In an HTTP challenge such as `WWW-Authenticate: Basic realm="Reports", charset="UTF-8"`, what do the realm and charset parameters actually control, and how should a password containing a character like 'ö' be encoded?

level: middleimportance: nice to knowfreq 30%

basics

~20 s

realm is a label naming the protection space, so clients know which stored credential to reuse and browsers can show it in the prompt. charset="UTF-8" — the only defined value — tells the client to encode credentials as UTF-8 before base64.

open as a page

RFC 7616 added SHA-256 to HTTP Digest Authentication alongside the legacy MD5 algorithm. How does a server offer both without breaking old clients, and what makes migrating an existing user base genuinely painful?

level: middleimportance: nice to knowfreq 14%

basics

~20 s

The server sends two WWW-Authenticate challenges, strongest first (SHA-256, then MD5), and the client picks the best it supports. The pain is storage: the server keeps H(username:realm:password) per algorithm, and it cannot compute the SHA-256 one from the MD5 one — so it must capture each user's password again, typically via a reset.

open as a page

In HTTP Digest Authentication, what roles do the server nonce, the client-generated cnonce and the nc counter play in replay protection, and what does a 401 challenge carrying `stale=true` mean?

level: seniorimportance: nice to knowfreq 20%

basics

~20 s

The server nonce makes each challenge unique and expirable; nc counts requests under that nonce so the server can reject a repeat; cnonce is client entropy that stops the server from choosing all hash inputs. stale=true means the nonce expired but the password was correct, so the client retries silently without re-prompting.

open as a page

A service authenticates every API call with HTTP Basic and verifies the supplied password against a bcrypt hash on each request. What operational consequences does that create, and how would you design around them?

level: principalimportance: nice to knowfreq 24%

basics

~20 s

Basic is stateless, so a deliberately slow password hash runs on every request. Throughput becomes cores divided by hash time, and unauthenticated traffic can exhaust CPU. Fix with short-TTL verification caching, fast hashes for high-entropy machine secrets, isolation and rate limits.

open as a page

You own authentication for a fleet of internal HTTP services that all accept `Authorization: Bearer` today. How would you decide where plain bearer carriage remains acceptable versus moving to sender-constrained carriage, and how would you roll that change out?

level: principalimportance: nice to knowfreq 22%

basics

~20 s

Decide per audience from a threat model: list who can observe headers, weigh the value behind each API, and adopt proof-of-possession only where observation is plausible and the loss is large. Roll out by dual-accepting both schemes, measuring, then enforcing per audience with a kill switch.

open as a page

A team wants an in-house HTTP authentication scheme sent as 'Authorization: AcmeSig <signature>' with a matching WWW-Authenticate challenge. What would you weigh before approving that, and what does the IANA HTTP Authentication Scheme Registry have to do with it?

level: principalimportance: nice to knowfreq 20%

basics

~20 s

Scheme names are a shared namespace registered with IANA, so an unregistered name risks collision and no generic client will understand it. Prefer a registered scheme, most often Bearer. Invent one only for a real gap such as request signing, then define its grammar, error signalling and registration path.

open as a page