An `integrity` attribute lists both a sha256 and a sha512 digest of one file — which does a conforming browser check?
answer
- not every listed digest is compared
- the algorithm tokens are ordered
- strongest supported algorithm wins
- same algorithm means either may match
- unknown token empties the metadata
basics
~20 sOnly the sha512 entry, on a client that supports it. The tokens sha256, sha384 and sha512 form an ordered set, and the client keeps only the strongest algorithm it supports, so a weaker entry beside it is never consulted.
solid answer
~40 sThe attribute value is a whitespace-separated list of entries, each a `hash-algorithm` token, a `-`, and a `base64-value`. The three valid tokens are an **ordered** set, and a conforming client first drops every entry whose algorithm it does not support, then keeps only the entries of the **strongest** algorithm that remains. So mixing algorithms is not an or-condition: beside a `sha512` entry, a `sha256` entry is dead text on any client that knows `sha512`. Two entries of the **same** algorithm are genuine alternatives — either matching digest accepts the file, which is how two builds ship behind one tag. Metadata naming only an algorithm the client does not support leaves an empty set, so the resource loads **unchecked**.
code
html · 5 lines<!-- two digests of ONE algorithm: either build is accepted -->
<script src="https://widgets.ads-partner.test/listing-carousel.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
crossorigin="anonymous"></script>go deeper
Recall the shape of one entry — algorithm token, hyphen, base64 digest — and that several entries are separated by whitespace. Know that listing more digests does not mean all of them are checked.
Explain the two steps, filter then select, and why that makes same-algorithm entries alternatives while mixed algorithms are not. Say what an unrecognised token does to the metadata set.
Show the operational reading: same-algorithm entries widen the accepted payload set, so a pin with a growing list of digests is an unreviewed build allowlist that should be pruned after each changeover.
The tradeoff is how digests are produced and rotated at all — generated from the bytes the host serves and verified in a pipeline, or hand-copied into markup where a wrong token removes the guarantee with no visible failure.
## The grammar of the value An `integrity` attribute holds **integrity metadata**: a whitespace-separated list of `hash-with-options` entries. Each entry is a `hash-expression` — a `hash-algorithm` token, a literal `-`, then a `base64-value` encoded per `RFC 4648` — optionally followed by a `?` and an `option-expression`. Options are reserved, and one a client does not recognise is **ignored** rather than treated as a parse failure. Nothing after a `?` can make an otherwise valid entry fail. The three valid algorithm tokens are `sha256`, `sha384` and `sha512`. The digest is taken over the raw bytes of the response and the base64 encoding of that digest is what you write, which is why the lengths are fixed: 44 characters for `sha256`, 64 for `sha384`, 88 for `sha512`. ## The algorithm set is ordered The rule most people get wrong is that those three tokens are not a menu of equals. They are an **ordered** set with the stronger algorithms later, and validation proceeds in two steps: 1. **Filter.** Drop every entry whose algorithm token the client does not support. 2. **Select.** Of what remains, keep only the entries using the **strongest** algorithm, and compare the fetched file against those. Entries using any weaker algorithm are not consulted at all. This is a selection rule, not a scoring rule — there is no notion of "two of the three matched". | what the attribute holds | client supporting all three | client supporting only sha256 | |---|---|---| | one `sha256` entry | compares that entry | compares that entry | | a `sha256` and a `sha512` entry | compares only the `sha512` entry | compares only the `sha256` entry | | two `sha256` entries | either may match | either may match | | one entry, algorithm unrecognised | nothing to compare; loads unchecked | nothing to compare; loads unchecked | ## Same algorithm: genuine alternatives Because selection keeps *all* entries of the winning algorithm and a match against **any** of them accepts the file, two digests of the same algorithm are a real or-condition. That is the mechanism behind a practice which otherwise looks like a mistake. The marketplace's widget vendor is moving between build pipelines, and for a fortnight either of two byte-different but equivalent files may be served to any visitor: 1. Pin **both** `sha384` digests in the one tag. 2. Either file now loads; anything else still fails. 3. When the changeover completes, remove the stale digest and the pin narrows back to one payload. The cost is exactly what it looks like: each extra digest of the winning algorithm is one more payload you have accepted. Two is a migration window; a list of eight is an unreviewed allowlist of builds. Mixing algorithms buys none of that. On a client that supports both, a `sha256` digest of build seven beside a `sha512` digest of build eight accepts build eight only — the older entry is discarded during selection and never compared. ## An algorithm the client does not know The filter step is also the migration lever. If every entry names an algorithm the client does not support, the filtered set is empty — and an empty set means there is **no integrity metadata to enforce**, so the resource loads as though the attribute had not been written. It does not fail closed. That cuts two ways, and both belong in the answer: - **The benefit.** An author can publish a digest in a stronger function without waiting for every client generation to catch up. Older clients keep checking what they understand, or check nothing if that is all you wrote. - **The cost.** "Ignore what you cannot parse" means an old client silently gets **no protection** rather than a loud failure — and a typo in an algorithm token behaves identically. `sha-256` or `sha2` is not a recognised token, so the entry is dropped, the set empties, and the file loads unchecked while the markup still looks pinned. There is no mismatch to notice, which makes this the quietest way to lose a guarantee you believe you have. ## Reading a value correctly Split on whitespace into entries; for each, take the part before `?` as the `hash-expression` and split it at the first `-` into `hash-algorithm` and `base64-value`; drop entries whose algorithm is unsupported; keep only the strongest algorithm surviving; compare the fetched bytes against each survivor and accept on the first match. An interviewer asking this is checking one belief: that a longer integrity value is a stronger one. It is not. A longer value is either a wider set of accepted payloads, when the algorithms match, or the same pin with inert text attached, when they do not.
- What happens if the only entry names an algorithm token the client does not recognise?The entry is filtered out, the metadata set is empty, and the resource loads **unchecked** — the same outcome as writing no attribute. It does not fail closed, which is why a mistyped algorithm token silently removes the guarantee instead of breaking the page.
- Can an option after the ? ever cause a failure?No. An `option-expression` follows a `?` and is reserved; a client that does not recognise the option ignores it and still evaluates the `hash-expression` in front of it. Options cannot invalidate an otherwise well-formed entry.
- Is listing a sha256 digest beside a sha512 digest a security weakness?Not on a client that supports both — the weaker entry is discarded during selection, so it neither weakens nor helps. The real cost is clarity: it reads like an or-condition to the next person, who may then write digests of two *different* builds under two algorithms and pin nothing useful.
saying these in an interview costs you the question
- Says every listed digest must match for the file to load
- Thinks a sha256 entry can still accept a file beside a sha512 entry
- Believes the first entry listed is the one compared
- Treats an unknown algorithm token as an automatic block
- Reads two digests of one algorithm as a copy-paste mistake