skip to content

A dependency was backdoored for six hours last Tuesday — what evidence proves whether it reached your production?

level: seniorimportance: should knowfreq 46%

answer

  1. records from the window, not today
  2. a fresh scan is a false clean
  3. the version set and the timestamps first
  4. lockfiles at built commits, plus build logs
  5. proxy fetch log gives the cleanest negative

basics

~20 s

Point-in-time records, not a fresh scan. You need the exact affected versions and window, the lockfiles at the commits that were built, build and dependency-resolution logs from that window, and the inventory of image digests actually deployed and running.

solid answer

~50 s

Start by pinning the question precisely: which versions were malicious, and between which timestamps were they retrievable. Then answer from records that describe that window, not from today's tree. The lockfile at each commit that was built tells you the resolved version, including transitive ones; build logs tell you which builds ran during the window and what they actually resolved, which matters for any build without a lockfile or with a floating range; the deployed inventory of image digests tells you what was running rather than what `main` says today; and registry or proxy logs tell you whether the bad version was ever fetched at all. That last one often produces the cleanest "never downloaded" evidence. Rescanning `main` is the classic false clean, because the version has already been yanked or bumped. Write the answer as affected, not affected with the evidence named, or still determining.

go deeper

for a junior

Know that the answer lives in the lockfile and the deployed artifact, not in the dependency file on the main branch, and that transitive dependencies count too.

for a middle

Be able to walk the evidence chain: affected version range and window, resolved versions at the built commits, builds that ran in the window, digests actually deployed.

for a senior

Demonstrate the instinct to preserve decaying evidence early and to distinguish what is true now from what was true during the window; deliver a claim with named sources.

for a principal

Own the pre-work and the promise: what records the organisation must keep to answer within a contractual window, and how you word a partial answer to a customer without over-claiming.

## The question you are actually being asked A headline compromise lands on Monday morning. A regulated SaaS has told its customers it will answer material supply chain questions within a contractual window — say seventy-two hours. The question is not "are we secure", it is "did the malicious version of this component enter anything we built, shipped or ran, and can you show your work". That word *show* is the whole difficulty. An assertion is worthless to a customer's security team and worse than worthless to an auditor; what they want is a claim tied to a record that existed before you went looking. Containment — freezing pipelines, rotating anything the malicious code could have read — runs on its own track and is a separate discipline. This question is about the evidence trail. ## Step one: pin the question Before touching any repository, establish three facts and write them down: the **exact affected version set** (a version range, not "the latest ones"), the **window** during which those versions were retrievable from the registry, and **what the malicious code did on which trigger** — for example, whether it ran at install time or only when a particular code path executed. Every subsequent search is parameterised by these three, and getting the version set slightly wrong is how teams produce a confident answer to the wrong question. Do not take the vendor's blog summary as the version set if a machine-readable advisory exists. ## Step two: search records, not the present The defining mistake is answering with a fresh scan. By the time you scan, the bad version has usually been unpublished from the registry, and your dependency file may have already been bumped by an automated update. A clean scan today is perfectly compatible with having deployed the backdoor last Tuesday. The evidence that survives is historical: - **Lockfiles at the commits that were built.** A lockfile records resolved versions across the whole transitive graph, so `git log`-style queries over lockfiles across every service and every release tag are the primary source. This is where the "we never resolved that version anywhere" answer comes from, and it covers transitive depth, which manifests do not. - **Build logs and resolution output from the window.** These matter precisely where the lockfile story is weak: builds that did not use a lockfile, ranges that could float, base images that were rebuilt during the window and pulled fresh dependencies inside their own layers, and any build that ran an update step. - **Registry proxy or artifact-cache logs.** If everything flows through an internal proxy, its download log is the highest-quality evidence available: either the malicious version was requested during the window or it never was. This is the difference between "we believe we are unaffected" and "no client in our estate ever fetched it". - **The deployed inventory.** Which image digests are running now and which were running during and after the window. `main` is not production; a service may still be running a build from before the last dependency bump, or after it. ## Step three: preserve the evidence Evidence decays fast during an incident. Log retention on the proxy may be days. Automated dependency updates will rewrite the lockfiles you are about to inspect. Ephemeral build agents discard workspaces. An early, unglamorous action is to extend retention and snapshot the relevant records before the investigation gets interesting. ## Step four: write the answer in a form that survives scrutiny Three honest outcomes, and they read very differently: - **Not affected, with evidence.** "Across 214 services, no lockfile at any commit built between <window> resolved the package in the affected range; the internal proxy has no fetch of any affected version; no deployed image digest contains it." Each clause names its source. - **Affected.** Name the services, the builds, the artifacts and the environments, and what the malicious code could have reached from there. - **Still determining, with a scope and a date.** Legitimate for a genuinely large estate, but only when it names which subset is already cleared and what is outstanding. The fourth option — "we use the package but we upgraded, so we're fine" — is the one that gets escalated back at you, because it answers a question nobody asked. ## Why this is the skill being tested An interviewer asking this is checking whether you understand that incident exposure is an *inventory and records* problem rather than a scanning problem, and whether you have the reflex to distinguish what is true now from what was true during the window. The teams that answer these well are the ones that built the records before they needed them: lockfiles committed and complete, builds logged, deployments recorded by digest, dependencies fetched through one path that keeps a log.

  • Your lockfiles are clean, but a service's container image was rebuilt during the window. Are you done?
    No. A rebuild pulls whatever the base image and any inside-the-image install steps resolve at that moment, which may sit outside the lockfile you checked. Treat every image built during the window as a separate item: inspect the layer contents or the build log for that specific digest, and compare against the affected version set rather than assuming the manifest governs everything in the image.
  • How would you shorten this exercise from days to hours before the next one?
    Build the records in advance. Commit complete lockfiles everywhere, route every dependency fetch through one proxy with useful retention, record deployments by artifact digest rather than by tag, and keep a queryable inventory of what each artifact contains. The response then becomes a query against existing data instead of a survey of every team.
  • What do you say when a customer asks for the answer before you have it?
    Give the scope and the mechanism, not reassurance. State which parts of the estate are already cleared and on what evidence, what remains, why it remains, and when you will come back. A precise partial answer with a named next update holds up far better than an early "we are not affected" you later have to retract.

saying these in an interview costs you the question

  • Answers by rescanning the main branch today
  • Cites the vendor blog post as the affected version set
  • Ignores transitive resolution and checks only direct dependencies
  • Confuses what main declares with what production runs
  • Says not affected without naming any evidence source

context